C language and operators [duplicate] - c

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.

Related

why using the assignment operator instead of equal to operator works in the following situation?

You should have a condition which should evaluate to true or false in order for an if statement to work. I don't understand how p=fopen("test.txt", "r") part of the following code evaluates to true or false since it only contains an assignment operator = and not a == operator.
#include <stdio.h>
int main()
{
FILE *p;
if(p=fopen("test.txt","r"))
{
printf("yes\n");
}
else
printf("no\n");
return 0;
From the C11 spec, chapter 6.5.16,
" An assignment expression has the value of the left operand after the assignment [....]"
So basically, you code is same as
p=fopen("test.txt","r");
if(p) { // or, if (p != NULL) for ease of understanding
// do something
}
From the C Standard )6.8.4.1 The if statement)
2 In both forms, the first substatement is executed if the expression
compares unequal to 0. In the else form, the second substatement is
executed if the expression compares equal to 0. If the first
substatement is reached via a label, the second substatement is not
executed.
and (6.5.16 Assignment operators)
3 An assignment operator stores a value in the object designated by
the left operand. An assignment expression has the value of the left
operand after the assignment,111) but is not an lvalue
So the value of the expression
p=fopen("test.txt","r")
is a pointer that in case of a successful call of the function fopen is not equal to 0.
If you don't use assignment, then p will contain uninitialized garbage. In general, it is considered bad practice to use the assignment operator inside conditions (most compilers will warn against it), because it's dangerous and hard to read. But it is perfectly valid, because the = operator has a result like most operators, in this case the value of p.
So the code in your example is a sloppier, worse way of writing
p=fopen("test.txt","r")
if(p)
which in turn is a sloppier version of
if(p != NULL)

How x?y:a?b:c will be evaluated?

Associativity of conditional operator is from right to left so the right most conditional operator should be solved(testing whether a is true or not) first but the book mentions that first x will be tested
The fact that the conditional operator associates to the right means that x?y:a?b:c will be parsed as if it had been written x?y:(a?b:c). If it associated to the left, it would have been parsed as (x?y:a)?b:c, which would almost certainly have been a surprise (unless you are used to PHP).
But neither of these parentheses change execution order. The conditional operator's first operand is always evaluated first.
The expression
int result = x?y:a?b:c;
can be written as
int result;
if (x)
{
result = y;
}
else
{
if (a)
{
result = b;
}
else
{
result = c;
}
}
So x must be evaluated first to determine whether the if block or the else block will be executed.
Note that the ternary operator only evaluates the expression that it needs to. When x is true, y is evaluated. When x is false, the subexpression a?b:c is evaluated.
In fact, the C standard requires that the code only evaluate the expression that's needed. Here's what it says in section 6.5.15/p4:
The first operand is evaluated; there is a sequence point between its
evaluation and the evaluation of the second or third operand
(whichever is evaluated). The second operand is evaluated only if the
first compares unequal to 0; the third operand is evaluated only if
the first compares equal to 0; the result is the value of the second
or third operand (whichever is evaluated), converted to the type
described below.
In the expression x?y:a?b:c,
the first operand is x
the second operand is y
the third operand is a?b:c
So the standard expressly forbids the code from evaluating any part of a?b:c unless x compares equal to 0.
The associativity only determines how the operands are interpreted. The first, second, and third operands listed above are based on right-to-left associativity.
If the associativity of the ternary operator was left-to-right, then
the first operand would be x?y:a
the second operand would be b
the third operand would be c

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

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.

Comma-Separated return arguments in C function [duplicate]

This question already has answers here:
What does the comma operator , do?
(8 answers)
Closed 7 years ago.
While completing a C programming test, I was given a question regarding the expected output from a function which seem to return two values. It was structured as follows:
int multi_return_args(void)
{
return (44,66);
}
The question caught me by surprise and inherently thought that if possible the first argument would be passed to the caller.
But after compiling it, the result is 66 instead. After a quick search I couldn't find anything about structuring a return statement like this so was wondering if some could help me.
Why does it behave like this and why?
The comma operator evaluates a series of expressions. The value of the comma group is the value of the last element in the list.
In the example you show the leading constant expression 44 has no effect, but if the expression had a side effect, it would occur. For example,
return printf( "we're done" ), 66;
In this case, the program would print "we're done" and then return 66.
In your code,
return (44,66);
is making (mis)use of the comma operator property. Here, it essentially discards the first (left side) operand of the , operator and returns the value of that of the second one (right operand).
To quote the C11 standard, chapter §6.5.17, Comma operator
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.
In this case, it is same as writing
return 66;
However, FWIW, the left hand side operand is evaluated as a void expression, meaning, if there is any side effect of that evaluation, that will take place as usual, but the result of the whole expression of the statement involving the comma operator will be having the type and the value of the evaluation of the right hand side operand.
This will return 66. There is nothing special about returning (44,66).
(44,66) is an expression that has the value 66 and therefore your function will return 66.
Read more about the comma operator.
Coma operator always returns the value of the rightmost operand when multiple comma operators are used inside an expression.
It will obviously return 66.

how the assignment is assigned for the if condition in below code

How this code works .Here i variable gets assignment of 55 value .But why the if statement fails since i gets 55 not 0, here else statement executed.How this interpretation happens .
As i expected output is Test Skills 55but its not.
#include<stdio.h>
void main()
{
int i;
i=0;
if(i=55,0,10,0)
printf("Test Skills %d",i);
else
printf("C Programing %d",i);
}
Can any one explain how it behaves in above code?
The comma expression
exp1, exp2
where exp1 and exp2 are any two expressions. This will evaluated in two steps:
exp1 is evaluated and its value discarded.
exp2 is evaluated and its value is the value of entire expression.
NOTE: Evaluating exp1 should always have a side effect; if it does not, then exp1 serves no purpose.
In your case
if(i=55,0,10,0)
i=55 is evaluated first and its value discarded (but side effect to i has been done, i.e, 55 is assigned to i). 0 evaluated then and discarded. 10 evaluated then and discarded. After then right most 0 is evaluated and it will be the value of entire expression ((but not the value of sub-expressions)) in if condition and make the condition false.
But side effect to i has been done and that's why you are getting output as55.
The comma operator is left to right.
You have values: 55,0,10,0 and the right-most value is 0 that means false.
Also assignment operator has higher priority then comma, so i is set to 55.
, operator executes from left to right. So the last value is 0 that makes the if false.
if(i=55,0,10,0) => if(i,0,10,0) => if(55,0,10,0) => if(0) => which returns false
^^^^-> Value of i
i is still 55 because , has the lowest precedence .
, operator executes it's left expression and returns the result of right expression as a result of , operator.
Other thing to note here is assignment operator has higher precedence then ,. That's why i got the value 55.

Resources