Use of assignment operators inside an 'if' condition in C++ - c++

If I use assignment operators or output functions inside the if condition, why is it taken as a "true" Boolean value?
For example, I do
if(cout << "a"){cout << "c";}
Or
if(int x=7){cout << "c";}
Or even
if(6){cout << "c";}
the outputs are indeed, "c" and "c" and "c" in each case. But we were told that, inside the if condition, we have to use an expression that finally evaluates to a Boolean value, like 1 or 0.
So what is the piece of information I am missing?

In each case the expression is converted to a bool. The value of this bool is true in the three cases that you use (it may not always be true).
if(cout << "a"){cout << "c";}
In this case the expression:
cout << "a"
If find the operator<<(std::ostream&, char const*) definition you will find that the return value is std::ostream&. So this will return a reference to the cout object (of type std::ostream). The stream object has a boolean conversion method explicit bool() which can be used to convert the object to bool. The result of this depends on the state of the object (if it is in a bad (failing) state it will return false).
So here you are checking that the last operation on the stream worked. If it does then print "c". This is commonly used on input streams to validate user intput.
int val;
if (std::cin >> val) {
if (std::cout << "A value was correctly read\n") {
// Add response worked.
}
else
{
// Something bad happened to std::cout
}
}
In the other cases you use int variables. These can be implicitly converted to bool. If the value is non zero then it is true (otherwise false).

Every value inside a condition (or with Boolean conversion) will give you true, unless it equal to 0.
(6) returns => 6 != 0 => true
(x = 7) returns => 7 != 0 => true
(cout << "aa") returns => ostream object.
bool context so calls `ostream::operator bool()`
If the stream is in good state => true
Otherwise => false
In C you can see it with NULL with this declaration:
#define NULL 0
which means that if an pointer equal to NULL it will return you a false in a Boolean conversion.
Examples in C++ for boolean expressions:
int a, b, *c;
char d;
bool e;
a = 0;
b = 2;
c = nullptr;
e = a; // false
e = b - 2; // false
e = c; // false
c = &a;
e = c; // true
e = b; // true
e = a + 1; // true
e = b ^ b; // false
d = 0;
e = d; // false
d = '0';
e = d; // true

In all the cases you've shown, it's still true that you've provided an expression that eventually is convertible to bool. If you look at the << operator of std::cout and similar ostreams, you'll see they all return a reference to the same stream. This stream also defines a conversion to bool operator, which is implicitly called in a context where a bool is expected. This particular conversion returns true if the stream has no errors. Secondly, int x=7 is an initialization, and it returns the value that x was just initialized with; 7 in this case. int in C++ can be implicitly cast to bool to be true if it's not zero, which is why both 7 and 6 evaluate to true in the second and third examples.

Related

variable value, after ternary operator

I have these lines of code:
int a = 10, b = 1;
a = --b ? b : (b = -99);
cout << "a= " << a << "b= " <<b<< endl;
the output gives me b=-99 as a is not equal to 0(which makes senses) but it also changes the value of a to a=-99 how?
Your code is the equivalent of:
int a = 10, b = 1;
b -= 1; // b == 0
int x;
if (b != 0) x = b;
else x = b = -99;
a = x;
// at this point a and b have the same value
The ternary operator works as follows:
if (--b != 0) { // b is not 0 means true
a = b;
} else { // b is 0 means false
a = (b = -99);
}
You assign the value to a, so --b is 0 which is considered as false. Then you assign to b value -99 and afterward, you assign b to a. So, both variables have their values -99 in the end. Hope it will help you.
According to ternary operator, The first argument is a comparison argument(condition), the second is the result upon a true comparison, and the third is the result upon a false comparison.
So In Your case, the condition is not True, So the false statement get executed.
so now b has -99.
In c, c++, java we've seen, assigns the value of the variable
a = b = -99
In this, the both a & b gets the same value. Like this, ternary operator also assigning the value of the variable from false statement .
(a = (b = -99 ))
I think what is confusing you here is that, in C, an expression (such as b = -99) has both consequences and a value. The consequence of b = -99 is that b is assigned the value of -99; but note also that the value of this expression is -99.
Thus, in a ternary expression, which takes the general form:
lhs = test ? v_if_true : v_if_false;
the expression test is first evaluated and lhs is assigned either v_if_true (if test evaluates to non-zero) or v_if_false (if test evaluates to zero).
In your case, test is --b. The consequence of this expression is that the value of b is decreased by one, and the value of the expression is the resulting (modified) value of b (which will be zero in your code).
So, your ternary expression assigns to a the value of the v_if_false expression which is b = -99 (the brackets you give add clarity to the expression, but don't change its evaluation). So, as mentioned above, this expression (as well as modifying b) also has a calculated value of -99, which is then given to a.
If you wanted to leave a unchanged in the case when the v_if_false expression is executed, then you could do this using the comma operator, as follows (though I would not recommend using such code):
a = --b ? b : ((b = -99), a); // If --b == 0, this becomes a = a
This works because the value of an expression containing the comma operator is the value of the sub-expression after (to the right of) the comma.

C++ syntax when initializing the instance variables

What does it mean in C++
int x;
x = GetMethod("OpponentCalledOnTurn") == 1;
Note : why is there a "==1" part.
I am Novice to c++.
This will set x to 1 if GetMethod("OpponentCalledOnTurn") == 1 evaluates to true and to 0 if it evaluates to false.
The underlying rule here: A boolean value can be converted to other integer types, that will result in 1 for true and 0 for false.
== is the equality comparison operator.
So GetMethod("OpponentCalledOnTurn") == 1 first calls the function GetMethod, passing the given string literal as an argument. The return value of that function call is then compared to 1. That comparison evaluates to either true if the return value equals 1, or false otherwise.
x = then assigns that true or false to x. Since x is of type int and not bool (the type of true and false), true is converted to 1 and false is converted to 0.
Effectively, if GetMethod("OpponentCalledOnTurn") returns 1, x will end up equaling 1, otherwise it will end up equaling 0.

How are these evaluated as true?

Consider the following examples:
int x;
if (x = 1)
//...
if (std::cout << "Is it true?")
//...
Both are evaluated as true, but why?
The if (x = 1) is essentially the same as tmp = (x = 1); if (tmp) ...
The "result" of operator << (const char *) is an ostream&, which has an operator bool that the compiler calls to make it "comparable". operator bool will return "false if there was an error, otherwise true". Before C++11, it would return a void*, but the meaning was the same ("false (= 0) if there is an error, true otherwise".
The result of assignment is its left operand, so the value of x = 1 is its left operand x, which has the value of 1 now. And any non-zero integer is treated as true in the condition.
Because x = 1 is an assignment setting x to 1, not a comparison for equality. Comparison is done via x == 1.
It is a common mistake. Often people write 1 == x to catch these errors, since assignment to a constant triggers a compile-time error.
Besides the assignment result for x as mentioned in the other answers the
if (std::cout << "Is it true?")
evaluates to true, because the statement is equivalent to
if ((std::cout << "Is it true?").good())
which checks for the stream state of std::cout.
Both statements return a value other than 0 and are thus considered to be "true".
If you assign a value to a variable, the result of that statement is the assigned value so you can assign multiple variables at once. For example, foo = bar = baz = 1. This works because baz = 1 yields 1, which is then assigned to bar, then to foo. So x = 1 has the value 1 and is thus true.
Next, the std::cout << "foo": the operator<< on a ostream returns the ostream so you can do things like std::cout << "foo" << "bar";. Again, there is a value returned that is not 0 and thus true.
In this condition x = 1 you firstly assign 1 to your x variable, and then test x, so it is exactly the same with:
x = 1;
if( x ) // which is 1, so true
About the output operator <<, the compiler will return true if the output-stream's state cout is ok. So it is not going to be a valid stream if some error occurs.
In the first one, you're assigning the value of 1 to x. A non-zero value will always evaluate to true in a condition.
For the second one, when std::cout << "Is it true?" is called, operator<< will return a reference to std::cout. At that point, the condition is simply reduced to:
if (std::cout)
//
This is now evaluating whether or not std::cout is in a good state.

the result of assignment Logic operation [duplicate]

This question already has answers here:
In C++ what causes an assignment to evaluate as true or false when used in a control structure?
(6 answers)
Closed 5 years ago.
int a = 5;
if(a = 5)
{
cout<<"111111"<<endl;
}
if(a = 0)
{
cout<<"22222"<<endl;
}
the reslut is
111111
Press any key to continue
acrroding to some commments,assign success,the result is true。
"a = 0" and a = 1" should assign success.but the result is only the first executed....
why ?
Some comments? That seems dodgy and in this case is incorrect.
The result of operator= on ints is the value that has been assigned. In this case a = 5 results in 5 and a = 0 results in 0. Since 5 evaluates as true you see "111111" but since 0 evaluates as false you don't see "22222".
As for why assignment results in the value being assigned, take the case with multiple assignments:
a = b = 5;
This is the same as:
a = (b = 5);
So for this to work as expected (b = 5) must return 5.
The result of a=5 is 5, and the result of a=0 is 0, so your program is like:
int a = 5;
if(5)
{
cout<<"111111"<<endl;
}
if(0)
{
cout<<"22222"<<endl;
}
Since the if statement requires a boolean value, 5 converts to true and 0 converts to false implicitly. so your program is now like:
int a = 5;
if(true)
{
cout<<"111111"<<endl;
}
if(false)
{
cout<<"22222"<<endl;
}
So it will print "111111" only.
"acrroding to some commments,assign success,the result is true"
The result of assignment is the result of expression in the left side.
"a = 0" and a = 1" should assign success.but the result is only the first executed....
Nope. 0 is false, you may as well have written"
if(0) { /* some code which will never execute */ }
The if statement evaluates the result of the expression between the parentheses, which means that the expression itself must be evaluated completely before the condition is checked.

isalpha(<mychar>) == true evaluates to false?

string temp is equal to "ZERO:\t.WORD\t1" from my debugger. (the first line of my file)
string temp = RemoveWhiteSpace(data);
int i = 0;
if ( temp.length() > 0 && isalpha(temp[0]) )
cout << "without true worked" << endl;
if ( temp.length() > 0 && isalpha(temp[0]) == true )
cout << "with true worked" << endl;
This is my code to check if first character of temp is a a-z,A-Z. The first if statement will evaluate to true and the 2nd to false. WHY?!?!?! I have tried this even without the "temp.length() > 0 &&" and it still evaluates false. It just hates the "== true". The only thing I can think of is that isalpha() returns != 0 and true == 1. Then, you could get isalpha() == 2 != 1. But, I have no idea if C++ is that ... weird.
BTW, I dont need to know that the "== true" is logically pointless. I know.
output was
without true worked
Compiled with CodeBlock using GNU GCC on Ubuntu 9.10 (if this matters any)
The is* functions are only guaranteed to return a non-zero value if true, NOT necessarily a 1. A typical implementation is table based, with one entry in the table for each character value, and a set of bits defining which bit means what. The is* function will just AND the right bitmask with the table value, and return that, which will only be the value 1 for whichever type happens to have been given bit position 0.
E.g.:
#define __digit 1
#define __lower 2
#define __upper 4
extern int __type_table[];
int isdigit(int c) {
return __type_table[c+1] & __digit;
}
int isalpha(int c) {
return __type_table[c+1] & (__lower | __upper);
}
int islower(int c) {
return __type_table[c+1] & __lower;
}
int isupper(int c) {
return __type_table[c+1] & __upper;
}
Where __type_table is defined as something like int __type_table[UINT_MAX+1]; and would be initialized so (for example) __type_table['0'+1] == __digit and __type_table['A'+1] == __upper.
In case you care, the '+1' part is to leave a spot at the beginning of the table for EOF (which is typically defined as -1).
isalpha doesn't return true, it returns non-zero. This is quite common for API designed for C.
Note that in the expression isalpha(ch) == true, the subexpression true is promoted to type int with value 1.
Well, the documentation suggests that it returns either zero or non-zero, not necessarily just false or true. So you'd better check (isalpha(temp[0]) != 0).
Do not isalpha(ch) == true, but !!isalpha(ch) == true