What does this statement tell please explain if(!(!x) && x)
#include<stdio.h>
int main(){
int x=5, y=10;
if(!(!x) && x)
printf("%d",x);
else
printf("%d",y);
return 0;
}
if(!(!x) && x) is equivalent to if(!!x && x).
!!x is 1 if x is non-zero and 0 if x is zero.
Furthermore, the expression simplifies to (!!x) since && x is a tautology as x is a non-volatile int type. But this collapsing the value to either 0 or 1 is exactly the behaviour of the if conditional, so the if simplifies to if (x).
In c, true and false are 1 and 0 respectively.
!(!x)
If x is zero, then (!x) evaluates as true (1), then !(true) evaluates as false.
The if statement is always false in such case.
if(!(!x) && x)
However, if x was non-zero, then !!x is true
true && true
You could simplify this if statement with
if(x)
Looking at the assembly generated by GCC 10.1 on https://godbolt.org/z/7kwDdJ
xor eax, eax // eax = 0
test edi, edi // perform bitwise & and set Zero, Positive, or Negative flag
sete al // Sets lower 8-bits in eax to 1 if the zero flag is set or to 0 otherwise.
ret
In short, GCC is reducing if(!(!x) && x) to if (x & x)
! is the not operator. It reverses 1 to 0 and vice versa. In your problem !(!x)
evaluates to x and so (!(!x) && x) will evauate to a true condition so x will be printed
In C language non-zero values are considered True and zero(0) is considered False. On the other hand, Logical Not (!) operator determines the opposite of something. For example: in your code, x = 5, So the value of !x will be 0, because x = 5 means the variable x holds a true value. So, not true = false = 0. Then the value of !(!x) = !(false/0) = not false = true = 1.
Remember that, logical NOT(!) operator doesn't change the value.
So ultimately !(!x) means true.
if(!(!x) && x) = if(true && true) = if(true)
This is why, if block will be executed.
Related
This question already has answers here:
Logical equality in C
(4 answers)
Closed 3 years ago.
What does
return x == y;
mean?
What does
return x == y;
mean?
Do a logical comparison between x and y which evaluates to an int holding either 1 or 0 depending on x and y being equal or not.
End the function and return the result as per 1..
First of all, let me make you understand what x == y means.
x == y compares x and y. The result of x == y will be true if x and y are equal, false otherwise.
In C, true is equivalent to any non-zero value (default is 1) and false is equivalent to zero.
So, if x is equal to y, x == y is equal to 1. Otherwise it is 0.
Finally, return x == y means that the value returned by the function will be 1 if both x and y are equal, 0 otherwise.
Consider the function,
int isEqual(int x, int y) {
return x == y;
}
int main() {
printf("%d", isEqual(1, 1)); // 1
printf("%d", isEqual(1, 2)); // 0
return 0;
}
== compares values of two variables. The compare results in true or false, so if x and y are equal, the result is true, else the result is false.
The return statement returns this result from the function.
In C, false is represented for a 0, and true for each other number (positives and negatives). So the function returns a 0 or a 1
According to the C Standard (6.5.9 Equality operators)
3 The == (equal to) and != (not equal to) operators are analogous to
the relational operators except for their lower precedence.108) Each
of the operators yields 1 if the specified relation is true and 0 if
it is false. The result has type int. For any pair of operands,
exactly one of the relations is true.
So in this return statement
return x == y;
there is used an expression with the equality operator ==. The value of the expression either 1 or 0 depending on whether x is equal to y or not. So the return statement returns either 1 or 0.
You could rewrite the return statement like
int result = ( x == y );
return result;
Consider for example an if statement in the condition of which there are compared two strings
if ( strcmp( s1, s2 ) == 0 )
{
puts( "The strings are equal each other." );
}
//...
You could write a separate function that would look like
int equal( const char *s1, const char *s2 )
{
return strcmp( s1, s2 ) == 0;
}
In this case the if statement would look like
if ( equal( s1, s2 ) )
{
puts( "The strings are equal each other." );
}
//...
The expression x == y yields an integer value, either 0 (when x is not equal to y) or 1 (when x is equal to y).
This gives you a bool (or boolean). If x is equal to y, it will return true, if not, then false. This will work the same in most programming languages that use the == operator.
According to my limited knowledge logical operators have left-right order of evaluation. By that rule it should evaluate x && y which is 1 and then it should evaluate == 1 in the if statement. But that is what not happening. Could anyone help me with this.
int main()
{
int x = 1, y = 2;
if (x && y == 1)
printf("true\n");
else
printf("false\n");
}
The order of operations is different than what you think.
Your expression is equivalent to
x && (y==1)
which is false in your case.
try this.
because of https://en.cppreference.com/w/c/language/operator_precedence
int main()
{
int x = 1, y = 2;
if ((x && y) == 1)
printf("true\n");
else
printf("false\n");
}
Try not to think about order of evaluation too much. It will often confuse you. The more important things to focus on is how the operators are grouped together and what the expression means.
The && operator has relatively low precedence. Almost any time you use it, it will have the form
if( condition_1 && condition_b )
and the interpretation is the obvious: "if condition_a is true and condition_b is true".
In your case, condition_a is just x, and condition_b is y == 1. So the interpretation is "if x is true and y equals 1".
What does it mean for x to be true? Simply that it's not zero. So we could expand this further: it's as if you had written
if ( x != 0 && y == 1 )
and the interpretation is "if x is not equal to 0 and y is equal to 1".
Remember, precedence says how the operators are grouped together. In your case, it's as if you had written
if ( x && ( y == 1 ) )
The == 1 part goes with the y. == binds more tightly than &&.
In terms of "order of evaluation", you can say that, yes, the compiler emits code that figures out whether x is true, and code that figures out whether y is equal to 1, before it uses && to determine whether they're both true. In the case of &&, we also know that it will decide whether x is true before it decides whether y is equal to 1. (But this is a rather special property of the && and || operators. It does not apply to most of the rest of the more ordinary operators like + and /.)
Because y == 1 is false as y = 2, written before if statement.
It does not evaluate they way you think. It evaluates x and then y == 1 and then &&, which is in your case in 1 && 0 and you have false result.
Here
if (x && y == 1)
above statement is equivalent to
if(x && (y==1) ) /* y==1 performed first, which is false */
As you can see here https://en.cppreference.com/w/cpp/language/operator_precedence
You want to get true as output, then first perform x&&y by keeping ().
if ( (x && y) == 1) { /* now () has higher precedence, so it perform x&&y first which results in true(1) and then 1==1 results in true */
}
else {
}
This is because of operator precedence.
Because of operator precedence the expression if (x && y == 1) results in if (x && (y == 1)).
So, the whole expression results to false because y==1 is false.
Use parenthesis and change it to if ((x && y) == 1) to get desired result.
I was taking a practice programming quiz, and I'm not sure why this program prints out -1:
#include <stdio.h>
int main()
{
int x = 1;
if (x-- && x-- && x--)
{
printf("%d\n", x);
} else
{
printf("%d\n", x);
}
return 0;
}
In C, logical operators such as && and || are evaluated using short-circuit evaluation, which essentially means that when a statement is guaranteed to be either true or false, any subsequent expressions in the statement are not evaluated.
In your program, only the first two conditions need to be evaluated to determine that the whole statement is false. The third expression is not evaluated.
if (x-- && /* evaluates true, and then x is decremented */
x-- && /* evaluates false, and then x is decremented */
x--) /* this is not executed */
Because this is a series of AND statements, logically, only one expression needs to be false for the whole statement to be false. When the second expression is determined to be false, there's no need to waste resources by evaluating the rest of the statement, so the else block is executed.
This causes the final value of x to be -1, instead of -2.
In C language, the test statement would end its operation as soon as the result can be determined. In this case, the first x-- returns 1 and set x = 0, the second x-- returns 0 and set x = -1.
1 && 0 can determine the result as 0, so the last x-- is ignored.
With a FALSE statement, the if-else choose the second printf as output and print the value of x : -1;
First start with x = 1, then the sequence of x-- && x-- && x-- goes like this, where each x-- represents the respective part of the condition.. (note that && acts as a sequence point).
x = 1 -> x = 1
x-- -> 1, x = 0
The result is 1 (1 && x-- && x--) so right-hand express of the first && is evaluated.
x-- -> 0, x = -1
The result is 0 (1 && 0 && x--) and the && short-circuit evaluation kicks in and the right-hand expression of the second && is not evaluated.
x--
Nope; as above this was not evaluated.
Since the condition is false (1 && 0 && dont_care_not_evaluated) it prints out the value, in the else case, while having only decremented x twice.
x-- -> 1-- it returns 1 here, after it gets decrements to 0
x-- -> 0-- it returns 0 here, what means false, after it gets decremented x to
x-- -> its unreahched, because this is an and condition, it stops if a part of it is false
so the final value will be -1 (what is not 0, so -1 is interpreted as true)
I understand a condition is supposed to be for example y==3, but y-3 is totally confusing to me. I can't understand this code. If y-3 is true it prints 1. How can y-3 be true or false?
The expression y - 3 results in a value which can be tested for truthness. In C 0 is false and any non-zero value is true. Saying if (y - 3) is essentially saying if (y - 3 != 0) or even more succinctly if (y != 3)
In C, everything what's 0 is false and everything what's non-zero is true.
When tested directly into a boolean context, integers can be evaluated like this.
0 is equivalent to false and all the other values are considered true.
In your code y - 3 will be equivalent to false only if y - 3 == 0, that is if y is 3.
A better style would be to write:
if (y - 3 != 0)
Or even:
if (y != 3)
if (E)
where E is an expression is equivalent to
if (E != 0)
In an if statement (or any statement with a condition), the condition is considered true if it's unequal to zero, false otherwise.
So this:
if (y - 3)
is equivalent to this:
if ((y -3 ) != 0)
which can (and should!) be re-written as:
if (y != 3)
The == operator, for example, yields an int value of either 1 or 0.
C does have a built-in Boolean type (called _Bool, introduced by the 1999 standard), but it didn't always exist, and it's not used in conditions. Of course you can use a _Bool value as a condition, but it's still tested (at least conceptually) for inequality to zero.
First, the expression 'y-3' will be evaluated. If the result is 0 (a.k.a, the value of y is 3), then the expression will evaluate to false, and the value "2" will be printed. If y is equal to any value other then 3, the condition will evaluate to true, and the value "1" will be printed
This would mean exactly the same
if ((y - 3) != 0)
printf("1");
else
printf("2");
So that's going to be true if it's not zero.
Since the associativity of '?' is from right to left,any 2 consecutive '?' operators must be treated as such,Right?
Now,
int x=-1;
int y=x?x++?x:-1:1;
I expect this to be executed as:
int y = x ? (x++?x:-1) : 1;
Now since its being executed from right to left,when encountering the first '?' in the statement,x's value is 0 and the expression is as
int y= x? 0 : 1;
hence i expected y to be 1,but it shows Zero on my dev-cpp.Where am i wrong?
You have the order of evaluation wrong. In a ? b : c, a is always evaluated first, then either b or c is evaluated.
I've marked up your example so that I can identify subexpressions:
c
int y=x?x++?x:-1:1;
a bbbbbbbb
(a) is evaluated, yielding -1, so (b) is evaluated. There, x++ is evaluated, yielding -1 again, so (c) is evaluated. At this point, x is 0.
Or, with more verbose, clearer code, it's as if you said:
int x = -1;
int y;
if (x != 0)
{
int new_x = x + 1;
if (x != 0)
{
y = new_x;
}
else
{
y = -1;
}
}
else
{
y = 1;
}
Operations:
Assign y to value =
if(x): --> x = -1, so true as it is non-zero
{
if(x): --> x = -1 ,so true as x will increment later due to post increment
x= x +1; --> increment x, so x = 0 . This is the value assigned. So y = 0;
else:
-1
}
else:
{
1
}
Hope this helps!
The answer to your question is that in C/C++ int y = x ? (x++?x:-1) : 1; we will hit two sequence points at ?. Any update operations to variable with in a sequence point will be effective after that sequence is over. So lets look at our example in hand.
First sequence point is first ? from left.
x=-1; (Actual Value)
x=-1; (Value used in expression)
y=-1?(x++?x:-1):1;
Second sequence point is second ? from left. As mentioned above the update operations are effective after sequence so even though x++ is there the value used in this sequence is -1 and updated value will be used in following.
x=0; (Actual Value, bcoz of x++)
x=-1; (Value used in expression)
y=-1?x:-1;
Now it will be
x=0; (Actual Value)
x=0; (Value used in expression)
y=x;
y=0;
Hope this make sense now.