Solving a problem using logical operators in C programming language - c

#include <stdio.h>
void main()
{
int a = 11, b = 5;
if(a == 7 || 10){
printf("True");
}
else
printf("False");
}
This is my problem, i saw it in a question and was asked what the output would be.
i put false but the answer was true, im trying to understand why because a is not equal to any of them and the condition for it to be true is that a be equal to at least one of them

The expression in the if statement
if(a == 7 || 10){
is equivalent to
if( ( a == 7 ) || ( 10 ) ){
As 10 is not equal to 0 then the second operand of the logical OR operator || always evaluates to the logical true. So the whole expression used in the if statement has a result of the logical true.
In fact as a is not equal to 7 (due to its initialization) then the above if statement is equivalent to
if( 10 ){

This:
if (a == 7 || 10)
Does not test if a is equal to either 7 or 10.
The == operator will evaluate to 1 if both operands are equal, and 0 otherwise. The || operator will evaluate to 1 if at least one operand is non-zero, and 0 otherwise.
Also, the equality operator has higher precedence than the logical OR operator. So the above parses as:
if ((a == 7) || 10)
So the expression will be true if either a==7 evaluates to non-zero or 10 evaluates to non-zero. The latter is true so the condition is true.

It is a logical error. The way you type it you don't check whether a == 7 OR a == 10 (as you wish), rather you check only if a == 7 and second condition if (10) is always true.
The fix is pretty simple actually:
void main()
{
int a = 11, b = 5;
if(a == (7 || 10)){
printf("True");
}
else
printf("False");
}

Related

In which order is && and || is evaluated in C?

if (2<3 || 3<4 && 5>6) printf("OK");
else printf("FAIL");
I am confused on how will the computer evaluate this if statement. My guess is (Since && comes before ||):
if ((2<3 || 3<4) && 5>6) printf("OK");
else printf("FAIL");
Since the statement is wrong the if should print FAIL. But the answer sheet says that the answer is OK.
My question is that when encountered with a situation like this should i evaluate from left to right or start from &&?
Test yourself. C does not evaluate all expressions when the result is known
https://godbolt.org/z/dE4y3M , https://godbolt.org/z/E_sxhX
#include <stdio.h>
int first(int x)
{
printf("FIRST\n");
return x;
}
int second(int x)
{
printf("SECOND\n");
return x;
}
int third(int x)
{
printf("third\n");
return x;
}
int fourth(int x)
{
printf("fourth\n");
return x;
}
int main()
{
if(first(0) || second(0) && third(1) || fourth(1)) printf("TRUE\n");
else printf("FALSE\n");
}
Logical and (&&) is higher than logical or (||), and is evaluated left to right.
See this.
if (2<3 || 3<4 && 5>6) printf("OK");
else printf("FAIL");
Is the same as...
if ((2<3) || ((3<4) && (5>6))) printf("OK");
else printf("FAIL");
If you check the operator precedence table, you'll see that && has higher precedence than ||. It also shows that < and > have higher precedence than both of them.
This means that this expression:
if (2<3 || 3<4 && 5>6)
Will be parsed as:
if ((2<3) || ((3<4) && (5>6)))
So the operands of the highest precedence operators are grouped first followed by the next highest. When dealing the operators of equal precedence, some group left-to-right while others group right-to-left.
It's good practice however to always use parenthesis around these operators to make it clear to the reader what your intentions are.
The logical AND operator has a higher priority than the logical OR operator. So the expression in the if statement
if (2<3 || 3<4 && 5>6) printf("OK");
is equivalent to the following expression
if ( 2<3 || ( 3<4 && 5>6 ) ) printf("OK");
The both operators are evaluated left-to-right.
And for the logical OR operator "If the first operand compares unequal to 0, the second operand is not evaluated." (C Standard)
So as the first operand of the logical OR operator 2 < 3 yields true then the result of the whole expression is not equal to 0 and evaluates as true (its value is the integer 1).

precedence and execution of the operators in the statement

can't understand how the boolean variable "check" is assigned 1 or 0. here 2 == 2 is true but the 2 is not equal to 3 so it should be false.....
/* practicing the precedence of assignment operator */
#include <stdio.h>
int main() {
_Bool check;
check = (2 == 2 != 3);
printf("the value of _Bool is %d\n",check);
return 0;
}
i expect the result to be false
What actually happens is like this
(2 == 2 != 3)
becomes
(2 == 2) != 3)
which is
(1 != 3)
which in turn becomes
(1)
Perhaps what you needed was
(2 == 2 && 2 != 3)
Operator precedence is the same for == and !=, since they both belong to the same group equality operators. To separate operators with same precedence, we use operator associativity of that group, in this case left-to-right. Meaning that 2 == 2 != 3 is guaranteed to be parsed as (2 == 2) != 3. So we get:
2 == 2 -> 1
1 != 3 -> 1
Notably both == and != have higher precedence than =, so the parenthesis in your expression = (2 == 2 != 3) isn't needed (but good practice to use if you are uncertain about precedence).
Regarding order of execution/evaluation, that's another term not to confuse with operator precedence. The order of evaluation of the == and != operands in your expression is unspecified, meaning we can't know which one that will get executed first.
In this case it doesn't matter, but if we had this check = a() == b() != c();, it could have. Here, we can't know which of the 3 functions that are executed first. We only know that operator precedence says that the result of a should be compared with the result of b before the result of c, but the function c may still be executed first.
Two things:
The equality operators have same precedence and left to right associativity, so (2 ==2 != 3) is the same as ((2 == 2) != 3) which is (1 != 3) which is true.
The equality operations return an int value as result, so using a _Bool (or, bool with stdbool.h) is not necessary.

Could anybody explain how "if" statement executed here

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.

Assignment operators in if statement

int a = 0, b = 0, c = -1;
if (b = a || b == ++c )
a+=3;
Why are the values of a,b and c 3 , 1, 0 respectively? More specifically, why is b 1 and not 0?
Because || has higher precedence than =, so it's being parsed as if you'd written.
if (b = (a || (b == ++c)))
This calculates a || (b == ++c). This is true because b == 0 and ++c == 0, so b == ++c is true, and true is 1.
Add parentheses to get what you want:
if ((b = a) || (b == ++c))
But IMHO it's generally best to avoid writing such complex expressions. Do them as separate statements:
b = a;
if (b || b == ++c)
Once you are clear with the precedence of operators,it will be easy for you to tackle such type of questions.Go through this to know about operator precedence in C.
You should see my answer after going through the precedence list because then it will get more easily inside your mind.
Now,coming to your question....
Out of all the operators used in the above code, ++c has the highest precedence.So the value of c becomes 0 and then value of c is compared to value of b here b == ++c which evaluates to true i.e 1 and now || of 1 and a is taken which is 1.
And finally this result 1 is assigned to b.So the overall execution of if statement evaluates to true and value of a is incremented by 3.
Hence finally the value of a=3,b=1 and c=0.

Short circuit evaluation with both && || operator

I know what is short circuit evaluation in C.
a && b (operand b is not checked if a = 0)
a || b (operand b is not checked if a = non zero)
But I am stuck at this question
int x = 0;
if (5 || 2 && ++x)
printf("%d", x);
This outputs 0.
My first thinking goes as follows:
According to precedence table , precedence is ++, &&, || (descending order)
++x: evaluated.x becomes 1.
2 && ++x evaluated. Both operands are evaluated.
|| is evaluated.
But according to this, 1 should be printed, not 0.
My second thinking goes as this:
5 || anything
anything is not evaluated because of short circuit evaluation, so no precedence comes into play here.
The expression 5 || 2 && ++x is equivalent to 5 || (2 && ++x) due to operator precedence.
The run time evaluates the expression 5 || 2 && ++x from left to right.
As we know in OR if first condition is true it will not check the second condition.
So here 5 evaluated as true and so (2 && ++x) will not be performed.
That's why x will remain 0 here.
Correct. The expression is short circuited. You can test it with this.
if(5 || ++x) {
printf("%d\n",x);
}

Resources