If I have a function such as
f1 (int a)
{
a = a % 2 ? a + 2 : a;
printf(”%c ” , ’a’ + a);
}
and I call f1(0)
What does a%2 as the condition mean?
It checks whether a is even or odd.
a % 2 gives remainder after dividing a by 2, i.e. 0 for even numbers and 1 for odd numbers. And then 0 or 1 is used as condition expression in ternary operator ?: to use either the first expression or the second expression as the final expression result.
Related
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 5 years ago.
Improve this question
#include <stdio.h>
int main()
{
int a=-1?2:5 + 8?4:5;
printf("%d\n",a);
return 0;
}
The output of above program is 2. But why ? Please explain
Write human-readable and understandable code. (Atleast, try to...)
int a=-1?2:5 + 8?4:5;
is the same as
int a = (-1) ? 2 : ( 5 + ( 8 ? 4 : 5) );
Reference: Operator Precedence
Now, let's compare that with the ternary operator condition, as mentioned in C11, chapter §6.5.15,
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),
So, in your case,
First operand is unequal to zero
So, it evaluates the second operand and the result, the value of the operand, is returned and stored into the LHS variable of assignment operator.
The statement :
int a=-1?2:5 + 8?4:5;
or better written with parentheses :
int a = (-1) ? 2 : ( 5 + 8?4:5);
which in turn means :
if (-1)
a = 2;
else {
if (8)
a = 9; //5+4
else
a = 10; //5+5
}
Any condition different than 0 is evaluated as true. So the condition if(-1) is different than 0, therefore true. Thus, the if block will be executed and a will get value 2.
Because a ? b : c evaluates to b if a is non-zero, and in your code a (-1) is non-zero and b is 2.
Lets look it step by step process,
int a=-1?2:5 + 8?4:5;
int a = (-1) ? 2 : ( 5 + 8?4:5);
for ternary operator (condition) ? return true: return false;
0 = False
Other than 0 = true
Hence -1 = true
int a = (true) ? 2 : ( 5 + 8?4:5);
int a = 2;
On a general note: the format:
x = a ? b : c;
Means:
if (a) // always results in true unless a = 0
x = b;
else
x = c;
Now, your statement when parenthesized:
int a = (-1) ? 2 : ( 5 + ( 8 ? 4 : 5) );
is merely a shortened if-else nested group of statements. When expanded, it looks something like:
if (-1) // since it is not zero, this is true
a = 2;
else // since the if-block is true, this is ignored by the compiler
{
if (8)
a = 5 + 4; // computes to 9
else
a = 5 + 5; // computes to 10
}
Hence, since the first if-statement is true, the compiler stores 2 in variable a.
As an aside, you should refrain from writing code that is hard to read. Even though your statement was shorter than writing an entire if-block, reading the if-else nested block is way easier to understand than reading your statement.
Can anyone help me?
Is there any difference between
if (!n / 10)
return;
and
if (n / 10 == 0)
return;
Yes, the two statements are different. !n / 10 is equivalent to (!n) / 10 and n / 10 == 0 is equivalent to !(n / 10).
Operator ! has higher precedence than that of / operator and therefore n will bind to ! first in !n / 10.
As #Kerrek SB pointed in his comment, !n will evaluated either to 0 or 1 so, the expression will always be false.
This statement
if (!n / 10)
return;
is equivalent to
if ( ( !n ) / 10)
return;
According to the description of the operatpr (6.5.3.3 Unary arithmetic operators)
5 The result of the logical negation operator ! is 0 if the value of
its operand compares unequal to 0, 1 if the value of its operand
compares equal to 0. The result has type int. The expression !E is
equivalent to (0==E).
Thus if n is equal to 0 then expression ( !n ) / 10 equal to expression 1 / 10 and as the both operands are integers then the result is equal to 0.
If n is not equal to 0 then expression ( !n ) / 10 equal to 0 / 10 and its result again equal equal to 0.
So the original expression is equivalent to
if ( 0 ) return;
It means that the return statement will be executed never.
As for the second statement
if (n / 10 == 0)
return;
when n is less than 10 then result of n / 10 (provided that n is integer) will be equal to 0 and you will get
if ( 0 == 0 ) return;
So the return statement in the second if statement will be executed when n is less than 10.
You're asking this because maybe you are not clear about how if statement works. So, let me explain it first.
The syntax of if statement is
if( expression )
{ procedure to follow }
Here expression to be used should be a logical one that it should result in true or false. Whenever the expression will result in true, the if statement is executed and vice-versa.
Another concept is that if the expression will result in 0 (false), the if statement will not get executed.
Now when you use if( n/10 ) , for n = 123, n/10 will result in 12 (the statement uses integers hence the result). Since it is not 0, it is treated as a true and the if statement will execute and n will be returned according to your code. Now n/10 doesn't change n, hence n(=123) will be returned and printed.
Now let's see about if( n/10 == 0 ) . For the first time when n=123 is n/10 will be 12 which is not equal to 0. So, here a false is generated and the if statement is not executed unlike the previous one.
According to your desired logic you should use if( n/10==0 ).
I am a college student who is taking his first programming class, in the process of studying a past exam I found this question:
give the following values of the print function
#include <stdio.h>
int main(){
float x;
int a = 5, b = 0;
x = a&b ? 2/8.f*5+b++ : a|b
printf("%f\n", x);
}
The printf displays 5.000 after running. What is tripping me up is the ?: operator. As I understand it, it works almost like an if, else statement, where if (condition) is true, then x, if not true then y. I don't understand the flow of the function.
is it saying that because the a&b yields 0 that it is not true, therefore x = a|b which after the operator runs yields decimal value 5?
Your understanding is exactly correct. The operator is called the ternary operator. In this case, the code evaluates a&b to be 0 or false, which causes it to use the value after the :, or a|b, which is 5. If, instead, b were to equal 1 for example, then a&b would evaluate to true, and x would equal the expression before the :, which evaluates to 2.25.
is it saying that because the a&b yields 0 that it is not true, therefore x = a|b which after the operator runs yields decimal value 5?
Yup.
The expression parses out as follows:
(a & b) ? ((2 / 8.f) * 5 + (b++)) : (a | b)
& is the bitwise AND operator; it will perform an AND operation on each bit of the two operands. Since a is 5 (101) and b is 0 (000), the result of a&b is 101 & 000 == 000.
Since a&b evaluates to 0, the expression following the ? is not evaluated; instead, (a|b) is evaluated. | is the bitwise OR operator. 101 | 000 == 101, which is 5.
Hence your result.
Sorry for this easy question but I couldn't find the answer, if I got a while loop that looks like this. Does it calculate before or after the comparison?
a = 0;
while(a++ < 5)
{
....
When it first runs the loop will it look at it as "1 < 5" or "0 < 5". Thanks
Comparison is done BEFORE the increment, but the body of the loop sees the value AFTER icrementation. So in the first run you'll compare 0 < 5, but in the loop a will have the value of 1.
The postfix operator is applied "after". The prefix operator is applied "before". In the case you've provided the first time 'a' is compared it's value will equal 0
Be careful, cause you can get in trouble with these operators if not used with care. Consider a[ix++] = a[ix] + 1; maybe it will do what you want, maybe not ... try it
Just read the other comment ... very good point that a will take on the ++ value insde the loop.
The result of the expression a++ is the current value of a, so the loop will start out as while ( 0 < 5 ).
The result of the expression ++a is the value of a + 1, so if you had written while ( ++a < 5 ), it would start out as while ( 1 < 5 ).
In both cases, a will be incremented by 1 as a side effect. Note that the side effect does not have to be applied immediately after the expression is evaluated; the only guarantee is that it is applied before the next sequence point (in this particular case, the sequence point is at the end of the conditional expression, so the body of the loop will see the updated value of a). So, if you have an expression like
x = a++ * ++b;
it will be evaluated as x = a * (b + 1), but there's no guarantee that a will be incremented before ++b has been evaluated, nor is there any guarantee that either will be incremented before the multiplication and the assignment. The following is one of many acceptable order of operations:
t1 <- b + 1
x <- a * t1
b <- b + 1
a <- a + 1
I have the following code which produces unexpected results to me:
#include < stdio.h >
int a = 0, value;
int main(void)
{
// Testing the evaluation order of multiple
// conditional operators:
value = (a == 3) ? 3 : (a = 3) ? 5 : 0;
printf("%d\n", value);
return 0;
}
I was expecting for this code to print 3, seeing that the conditional operator evaluates
from right to left and that there is a sequence point at the ? of the first-to-be executed
operation, whereas it actually prints 5.
Is it wrong to assume that side effects of an expression residing between two sequence
points also get calculated when the values of the expressions are?
If i add printf("%d\n" a); i get 3 printed though, so the side effect gets done.
Or is it just that control dosent really pass to the subexpression the value of which
is being calculated "first" officially?
I would rather bet on the latter because changing the value of 'a' to 3 and the rvalue
in the assignment of the second conditional to 4 resulted in short-circuit evaluation
of the first conditional expression, meaning that i got 3 printed for both 'a' and 'value'.
I got the above result on Lubuntu 14.04 with GCC 4.8.2 using the -std=c99 flag.
Thank you for anyone clearing me up on this matter!
The conditional operator does not "evaluate right to left". The standard (C11 6.5.15/4) says:
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)
So the expression (a == 3) ? 3 : (a = 3) ? 5 : 0; evaluates in these steps:
(a == 3) result is 0
(a = 3) result is 3, unequal to 0
5
So 5 is what is assigned to value.
You might be confusing the concept of how the conditional operator is evaluated with how the conditional operator associates (or groups). The syntax of C specifies that the expression:
(a == 3) ? 3 : (a = 3) ? 5 : 0;
associates or groups sub expressions like so:
((a == 3) ? 3 : ((a = 3) ? 5 : 0));
which is often described as 'associates right'. However, this grouping/associativity doesn't affect the fact that the expression is still evaluated left-to-right and that the second conditional expression only evaluates after the first operand in the 'outer' conditional expression is evaluated.
Let's trace through this one part at a time. You have this expression:
value = (a == 3) ? 3 : (a = 3) ? 5 : 0;
Since a starts off at 0, we skip the 3 branch of the first ?: and look at the second branch, which is
(a = 3) ? 5 : 0
The condition here is a = 3, which sets a to 3 and then evaluates to the new value of a, which is 3. Since 3 is nonzero, we take the first branch of the ?:, so the expression evaluates to 5. The net effect is that a is set to 3 and value is set to 5.
The language spec guarantees that the evaluation order is indeed what you think it should be - the "if" and "else" branches of the ?: operator are guaranteed not to execute unless the condition works out as it does, so there are sequence points here. I think you just misunderstood the effect of the a = 3 operation.
Hope this helps!
The conditional operator evaluates left-to-right (evaluating the condition before either of the branches). You may be confusing this with its right-associativity (in which it appears to bind right-to-left).
Your conditional expression essentially results in the following logic:
if(a == 3) {
value = 3;
} else {
if(a = 3) {
value = 5;
} else {
value = 0;
}
}
Note that the conditional doesn't execute a branch until after the condition is evaluated.