precedence and execution of the operators in the statement - c

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.

Related

I was practicing decision control in c and i encountered a problem with logical operators [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 days ago.
Improve this question
#include <stdio.h>
int main()
{
int i=4, j=-1, k=0, w, x, y, z;
w = i||j||k;
x = i&&j&&k;
y = i||j&&k;
z = i&&j||k;
printf("w = %d, x = %d, y = %d, z = %d", w,x,y,z);
return 0;
}
I was solving problems regarding C decision control with logical operators and I encountered a problem which I just cannot understand as the output was not something that I was expecting.
The output is:
w = 1, x = 0, y = 1, z = 1
There's a few things you need to know here:
Any expression in C that has the value 0 is regarded as false, and any other expression with any other value different than zero is regarded as true.
The result of boolean logical operators like &&, ||, == etc is always 0 (false) or 1 (true).
Operator precedence specifies how these expressions are parsed: that is, which operand belongs to which operator. For example in case of y = i||j&&k;, the operator precedence is && (highest) then || then = (lowest). Therefore that expression is equivalent to:
y = ( i || (j&&k) );
The logical AND && and OR || operators are some of the few operators in C that have a well-defined order of evaluation. They are guaranteed to be executed from left to right. They are guaranteed to stop evaluation in case only the left operand is all that's needed to tell if the expression will become true or false.
That's a common beginner FAQ, read all about it here: Is short-circuiting logical operators mandated? And evaluation order?
For the previous example y = ( i || (j&&k) );, i is the left-most operand of || which is what matters. It is 4, therefore true. true || anything is always true, so the rest of the expression is not evaluated.
w = i||j||k;
x = i&&j&&k;
y = i||j&&k;
z = i&&j||k;
is equivalent to:
w = ((i != 0) || (j != 0)) || (k != 0);
x = ((i != 0) && (j != 0)) && (k != 0);
y = (i != 0) || ((j != 0) && (k != 0));
z = ((i != 0) && (j != 0)) || (k != 0);
Some things to note:
The value 0 represents
false.
Any value different from
0 represents logical
true.
Logical operators returns
either true or false.
Operators that have the same
precedence are bound to their
arguments in the direction of
their associativity.¹
The associativity of && is
from left-to-right. So this
statement:
x = i&&j&&k;
is parsed as:
x = ((i != 0) && (j != 0)) && (k != 0);
Remember that && takes precedence
over ||. So
y = i || j && k;
is parsed as:
y = i || (j && k);
— #Weather Vane
The logical-AND operator has
type
int and the value 1 if both lhs
and rhs compare unequal to zero.
It has the value ​0​ otherwise (if
either lhs or rhs or both compare
equal to zero).
There is a sequence point after
the evaluation of lhs. If the
result of lhs compares equal to
zero, then rhs is not evaluated at
all (so-called short-circuit
evaluation).²
The logical-OR operator has type
int and the value 1 if either lhs
or rhs compare unequal to zero. It
has value ​0​ otherwise (if both lhs
and rhs compare equal to zero).
There is a sequence point after
the evaluation of lhs. If the
result of lhs compares unequal to
zero, then rhs is not evaluated at
all (so-called short-circuit
evaluation).³
[1] - [2] - [3] — cppreference.com

Solving a problem using logical operators in C programming language

#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");
}

Explanation of shortcuts in C

Can someone explain what exactly is happening in these two statements listed below:
1) int enabled = val == 0; //val is an int
2) int sync = param || (foo->delay == NULL); //param and delay is both int
int enabled = val == 0;
read as
int enabled = (val == 0);
and
(val == 0)
will be either 0 or non zero if val is 0 or not. enabled will then be initialized with that value
Equivalent to:
int enabled;
if(val == 0)
{
enabled = 1;
}
else
{
enabled = 0;
}
now you do that same analysis on the second one
You will set the variable enabled to 1 if val is equal to 0 and 0 otherwise.
sync will be equal to 1 if param is non-zero and in case it is 0 then it will be 1 if foo->delay is NULL else it will be 0.
From standard §6.5.9p3 backing up what I said:
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.
Also in case || there is standard saying the evaluation logic: from §6.5.14
Unlike the bitwise | operator, the || operator guarantees left-to-right evaluation; if the second operand is evaluated, there is a sequence point between the evaluations of the first and second operands. If the first operand compares unequal to 0, the second operand is not evaluated.
Also in the same section the rule which dictates what will be the result if param is non-zero.
The || operator shall yield 1 if either of its operands compare unequal to 0; otherwise, it yields 0. The result has type int.
C only adopted a true boolean type from C++ with C99, though it named it _Bool so it wouldn't conflict with pre-existing code and provided the header <stdbool.h> to make it nicer.
The prior convention that only 0 is considered falsey (a literal zero, which in a pointer-context is a null-pointer), and anything else truthy was not changed. (That's the reverse to how command shells do it by the way.)
All boolean operators and conversion from _Bool use canonical values of 0 and 1.
That should be enough history and details to understand the code.

Does "true" in C always mean 1?

Please consider these piece of C code:
if ((value & 1) == 1)
{
}
Assuming value equals 1, will (value & 1) return 1 or any unspecified non zero number?
§6.5.8 Relational operators
Each of the operators < (less than), > (greater than), <= (less than or equal to), and >= (greater than or equal to) shall yield 1 if the specified relation is true and 0 if it is false.) The result has type int.
§6.5.9 Equality operators
The == (equal to) and != (not equal to) operators are analogous to the relational operators except for their lower precedence.) 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.
§6.5.13 Logical AND operator
The && operator shall yield 1 if both of its operands compare unequal to 0; otherwise, it yields 0. The result has type int.
§6.5.14 Logical OR operator
The || operator shall yield 1 if either of its operands compare unequal to 0; otherwise, it yields 0. The result has type int.
Does “true” in C always mean 1?
No. Any expression that evaluates to a non-zero value is "true" in C. For example,
if (-1) {
}
if (5-10) {
}
if( "string literal") {
}
are all "true" and pass the condition.
In your specific example, the relational operator == yields 1 which is also "true"(the same holds for all other relational operators as noted by Govind).
If you are really asking about whether the bit-wise AND (&) yields 1 when value is 1, then yes, value & 1 yields 1 (assuming value is an integer type -- & operator requires its operands to be integers).
In fact, you can probably try to understand the individual parts and (generally how the & and == operators behave) by using a simple program:
#include <stdio.h>
int main(void)
{
int value = 1;
printf(" value & 1 = %d\n", value & 1);
printf(" 2 & 1 = %d\n", 2 & 1);
printf("((value & 1) == 1) = %d", (value & 1) == 1);
}

Confusion with Associativity of Assignment operator in C

As we all know that Associativity of assignment operator is from right to left but
in the given code output should be zero if we go from right to left but output is 1 .
main()
{
int a=3,b=2;
a=a==b==0;
printf("%d",a);
}
How output is coming out to be 1 if we go by right to letf??
If we go by right to left then (b==0) should be Evaluated first and gives result 0 and then expression (a==0) is Evaluated also gives 0 and at last a's value will be 0.
Assignment is done RTL, but equality (==) isn't.
The statement is actually:
a = ((a == b) == 0)
The right hand side of the assignment is evaluated from left to right. In steps, this is what's happening:
a == b is 0
0 == 0 is 1
1 is assigned to a
Your code is equivalent to :
a = ((a == b) == 0);
Note, this is phrased this way as it was merged from this question. OP asked why a==b==c is equivalent to a==b && b==c in Objective C (which is a strict superset of C). I asked this answer to be migrated since it cites the specificatio where other answers here do not.
No, it is not, it's like (a==b) == c.
Let's look at a simple counter example to your rule:
(0 == 0 == 0);// evaluates to 0
However
(0 == 0) && (0 == 0) // evaluates to 1
The logic is problematic since:
(0 == 0 == 0) reads out as ((0 == 0) == 0) which is similar to 1 == 0 which is false (0).
For the ambitious student
A little dive on how this is evaluated. Programming languages include grammar which specifies how you read a statement in the language. Siance Objective-C does not have an actual specification I'll use the C specificification since objective-c is a strict superset of c.
The standard states that an equality expression (6.5.9) is evaluated as the following:
Equality Expression:
relational-expression
equality-expression == relational-expression
equality-expression != relational-expression
Our case is the second one, since in a == b == c is read as equality_expression == relational_expression where the first equality expression is a == b.
(Now, the actual result number follow quite a way back to a number literal, equality->relational->shift->additive->multiplicative->cast->unary->postfix->primary->constant , but that's not the point)
So the specification clearly states that a==b==c does not evaluate the same way as a==b && b==c
It's worth mentioning that some languages do support expressions in the form a<b<c however, C is not one such language.

Resources