how do we interpret the `||` and `&&` in an assignment statement? [duplicate] - c

This question already has answers here:
Evaluation of C expression
(8 answers)
Closed 7 years ago.
I have been coding from a long time though I'm still a student programmer/ I'm usually good at programming but when questions like the one below are asked I get stuck. What will be the output and why of the following program?
int main()
{
int i=4,j=-1,k=0,w,x,y,z;
w=i||j||k;
print("%d",w);
return 0;
}
output:
1
why this result? what does the statement w=||j||k; means?

i || j || k is evaluated from left to right. It does that:
i == 4, which is true, so ORing it with any other value will yield true. That's it1.
The rest of the statement is not evaluated because || and && are short-circuit operators, that is, if in your statement i != 0, neither j nor k will be evaluated because the result is guaranteed to be 1. && works similarly.
That's important to remember if you have something like f() || k(), where k has some side effect like an output to screen or a variable assignment; it might not be executed at all.
The bitwise OR operator | really ORs the bitwise representations of the values instead; it evaluates all its operands.
1 Thanks to #SouravGosh on that!

In your code,
w=i||j||k;
is equivalent to
w= ((i||j) || k);
That means, first the (i||j) will be evaluated, and based on the result (if 0), the later part will be evaluated.
So, in your case, i being 4, (i||j) evaluates to 1 and based on the logical OR operator semantics, the later part is not evaluated and the whole expression yields 1 which is finally assigned to w.
Related quotes, from C11 standard, chapter ยง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.
then, regarding the evaluation of arguments,
[...] If the first operand compares unequal to 0, the second operand is
not evaluated.
and regarding the grouping,
[...] the || operator guarantees left-to-right evaluation;

The result of boolean operators yields an int value of 0 or 1.
See 6.5.13 and 6.5.14, paragraph 3.
The [...] operator shall yield 1 [or] 0. The result has type int.

Related

Evaluating an expression containing logical and increment operators in c

I'm trying really hard to understand how this expression is evaluated in c even though I know the precedence and associativity of operators in c language
int i=-4,j=2,k=0,m;
m = ++i || ++j && ++k;
As far as I know the pre increment operators are evaluated first from left to right the the logical and is then the logical so the I value will be -3 the j value will be 3 the k value will be 1 and for m value its 1 but it seems that I'm mistaken.
I'm studying this for an upcoming exam and ill appreciate any help.
The part that you're possibly missing while trying to understand the logic behind the final values obtained is what is known as short circuiting in C.
A summary of what it is -
if the first operand of the || operator compares to 1, then the second operand is not evaluated. Likewise, if the first operand of the && operator compares to 0, then the second operand is not evaluated.
Going by the above rules, the unary operation on i (++i) returns with 1 and hence the following operands of the || statement are essentially ignored. Therefore, the value of all other variables remains unaffected and m receives the value 1.

How does this trick work? bool && printf() [duplicate]

This question already has answers here:
What is short-circuit evaluation in C?
(3 answers)
Closed last year.
How does this work?
int x = 0;
x && printf("Hello World!");
This will output nothing on terminal, but
int x = 1;
x && printf("Hello World!");
will output "Hello Wolrd!"
It is called short circuit evaluation of a logical expression. Logical expressions are evaluated until the result is undetermined.
In this case:
if x==0 logical AND will be false despite the other side of the
expression. printf will not be called.
if x==1 the result of AND is still undetermined. printf will be called.
The result of this AND operation is not used and compiler will warn you.
The C standard specifies the behavior of && in clause 6.5.13. Paragraph 4 says:
Unlike the bitwise binary & 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 equal to 0, the second operand is not evaluated.

How this logical operator works? [duplicate]

This question already has answers here:
Is short-circuiting logical operators mandated? And evaluation order?
(7 answers)
Closed 1 year ago.
#include<stdio.h>
int main()
{
int a=-10,b=3,c=0,d;
d= a++||++b &&c++;
printf("%d %d %d %d ",a,b,c,d);
}
How above expression is evaluates. I have read preceedence but still i am getting confused. Kindly give me the right solution of this in step by step.
In case of || and && operators the order of evaluation is indeed defined as left-to-right.So, operator precedence rules tell you that the grouping should be
(a++) || ((++b) && (c++))
Now, order-of-evaluation rules tell you that first we evaluate a++, then (if necessary) we evaluate ++b, then (if necessary) we evaluate c++, then we evaluate && and finally we evaluate ||.
I have a feeling this is a homework question, so I'll try to give extra explanation. There are actually a lot of concepts going on here!
Here are the main concepts:
Pre- and post- increment and decrement. ++a increments a before the value is used in an expression, while a++ increments a after the value is used in the expression.
Operator precedence. Specifically, && has higher precedence than ||, which means that the assignment of d should be should be read as d = (a++) || (++b && c++);
Expression evaluation order. The link shows a whole list of evaluation rules for C. In particular, item 2 says (paraphrasing) that for operators || and &&, the entire left side is always fully evaluated before any evaluation of the right-hand side begins. This is important because of...
Short-circuit boolean evaluation, which says that, for operators && and ||, if the value of the left-hand term is enough to determine the result of the expression, then the right-hand term is not evaluated at all.
Behaviour of boolean operators in C. There is no inbuilt boolean type in C, and operators && and || work on integer values. In short, an argument is 'true' if it is nonzero, and false if it equals zero. The return value is 1 for true and 0 for false.
Putting this all together, here is what happens:
After the first line, a is -10, b is 3, c is 0 and d is unset.
Next, the variable d needs to be assigned. To determine the value assigned to d, the left hand term of (a++) || (++b && c++) is evaluated, which is a++. The value USED in the expression is 10, however the value of a after this expression is -9 due to the post-increment.
For the purposes of the boolean operator, the value 10 is true, and therefore value of the || expression is 1. Because of short-circuit evaluation, this means that ++b && c++ is not evaluated at all, so the increments do not happen. Thus we have d = 1.
At the end, the values are: a = -9, b = 3, c = 0, d = 1.
So the program prints out -9 3 0 1.

C language and operators [duplicate]

This question already has answers here:
What does the comma operator , do?
(8 answers)
Closed 1 year ago.
#include <stdio.h>
int main()
{
int i=2;
if(i==3,4)
{
printf("If block");
}
else
{
printf("Else block");
}
return 0;
}
Why is this code returning "If block" ?``
The expression in the if statement:
(i==3,4)
Contains the comma operator. It evaluates its left operand, discards its value, then evaluated the right operand which is its result. This operator also has lower precedence than the equality operator ==, so this parses as:
((i==3),4)
So i==3 is first evaluated. Since i has the value 2 the comparison is false resulting in i==3 evaluating to 0. This value is discarded. Then 4 is evaluated which becomes the value of the entire expression. Since this value is non-zero, the if block is true, so "If block" is printed.
In the condition of the if statement
if(i==3,4)
there is used the comma operator.
From the C Standard (6.5.17 Comma operator)
2 The left operand of a comma operator is evaluated as a void
expression; there is a sequence point between its evaluation and that
of the right operand. Then the right operand is evaluated; the result
has its type and value
That is the above if statement can be equivalently written like
if( ( i==3 ), ( 4 ))
So according to the quote from the C Standard the left operand ( i == 3 ) is evaluated as a void expression that is its result is discarded. And the result of the whole expression is the value of the right operand that is of the expression ( 4 ). As this expression is not equal to 0 then the whole condition is evaluated as logical true and the sub-statement of the if statement is executed.
"Why is this code returning "If block" ?``"
The explanation of why the expression if(i==3,4) causes execution flow to go to the true branch is provided in good detail in the other answers. In short the idea that it evaluates its first operand and discards the result, Then uses the second operand to evaluate as the condition.
But, some might ask is this useful?
One use is to force a side effect prior to deciding which branch to flow to.
For example
if (numeric_read(str, &err), !err)
// ^ ^ result 'err' of side effect used in if evaluation.
^
// causes side effect by call function which assigns value to err.
(credit, in comments.)
The side effect here populates err, then discards the logical result of the call in the first argument. The value assigned to err is then used to select the branch.

How does operator precedence actually work in this program?

#include<stdio.h>
int main()
{
int i=-1, j=-1, k=-1, l=2, m;
m = (i++ && j++ && k++) || (l++);
printf("%d %d %d %d %d", i, j, k, l, m);
}
I am having confusions about how operator precedence is working in the evaluation of the logical expression in the given program.
The variable m will be assigned 0 or 1 depending on the value of the logical expression that follows it.
The first parenthesis will be evaluated and the overall result of two AND operations will be true or 1. But, since a short-circuit logical OR is used, the second parenthesis is not getting evaluated.
So, my question is if parentheses have higher precedence that all the other operators in that expression, why is not both the parentheses evaluated first, and then the OR operation performed?
That is, why is the output 0 0 0 2 1 and not 0 0 0 3 1?
EDIT:
What I have asked is somewhat different from this (suggested duplicate)
as I am emphasizing on the parentheses enclosing the second operand of OR operator.
Operator precedence comes into effect when there's an ambiguity.
In this case, the spec is quite clear.
The || operator shall yield 1 if either of its operands compare unequal to 0; otherwise, it
yields 0. The result has type int.
and, (emphasis mine)
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.
In your case,
(i++ && j++ && k++) || (l++);
(i++ && j++ && k++) is the left operand and (l++); is the right operand and the rest should be quite clear. :)
Operator precedence (and associativity) only determines how the expression should be parsed. It is a common mistake to confuse it with order of evaluation of the operands, which is different thing. Operator precedence is rather irrelevant in this example.
For most operators in C, the order of evaluation of the operands is not specified. Had you written true | l++ then l++ would have been executed. The "short-circuit evaluation" is the reason why this doesn't happen in your code. The && || operators is a special case, since they explicitly define the order of evaluation. The right operand of || is guaranteed not to be evaluated in case the left operand evaluates to non-zero.

Resources