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.
Related
This question already has answers here:
What is short-circuit evaluation in C?
(3 answers)
Closed 1 year ago.
I'm struggling to understand the behavior of the below code:
#include <stdio.h>
int main(void)
{
int i;
int j;
int k;
i = 7;
j = 8;
k = 9;
printf("%d\n", (i = j) || (j = k));
printf("%d, %d, %d\n", i, j, k);
return (0);
}
Output:
1
8, 8, 9
Question:
I understand that expr1 | | expr2 has the value 1 if either expr1 or expr2(or both)has a nonzero value.
The value of i increased from 7 to 8 because j's value is assigned to i but the same way why does the value of the j is not increased even though j = k? I was expecting an
output
1
8, 9, 9
From the C standard (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.
The above behaviour is commonly referred to as operator short circuiting.
In your example, since (i = j) is not zero the second operand is thus not evaluated.
First of all,
true || true is true
true || false is true
false || true is true
false || false is false
So operator || is calculating the first expression and if it is true, it does not check the second one.
In yours particular situation (i = j) is equal to 8, which is considered true, because int values are considered false only if they are equal 0.
So the second (j = k) is never computed, which leads to your result.
#include <stdio.h>
int main(void){
int n = 0, y = 1;
y == 1 ? n = 0 : n = 1;
if (n)
printf("YES");
else
printf("NO");
return 0;
}
Can some one explain why does the line with the ternary operator give a lvalue error. I have a very abstract idea of what lvalue is. Let me give my abstraction, correct me if I am wrong. lvalue is typically the address or we can say the variable where we store a constant value and the value of a variable or a constant is a rvalue. But I don't understand why is there an lvalue error in the assignment part of the ternary operator which states n = 0 : n = 1. It would be really helpful if I could get a proper understanding of what is wrong with my code.
The ternary operator ?: has higher precedence the assignment operator =. So your expression parses as:
(y == 1 ? n = 0 : n) = 1;
This gives you an expression on the left side of the assignment that is not an lvalue and therefore not assignable.
The ternary operator evaluates to either the value of the second part or the value of the third part, and these values are what you want to assign to n, so you could instead write it as:
n = y == 1 ? 0 : 1;
Or you could invert the condition and get rid of the ternary entirely:
n = y != 1;
The reason is that the ternary operator has higher precedence than assignment. So the expression is parsed as if you'd written:
(y == 1 ? n = 0 : n) = 1;
This is not a valid assignment because the result of the conditional operator is an rvalue, not an lvalue, so you can't assign to it.
You can solve the problem by adding parentheses around the assignments.
y == 1 ? (n = 0) : (n = 1);
But since you're assigning to the same variable, the more normal way to write this would be:
n = y == 1 ? 0: 1;
You can also take advantage of the fact that the result of a comparison operator is a boolean, either 0 or 1, so you can write simply:
n = y != 1;
This question already has answers here:
Comparing a variable to a range of values
(7 answers)
Closed 4 years ago.
why does the following if-statement return 1 (true)?
int main() {
short a = 1;
short b = 5;
short c = 4;
if (a<b<c)
printf("true \n");
else
printf("false \n");
return 0;
}
It is obviously not the same as
if(a<b && b<c)
because this returns false.
Thank you
The relational operators (<, <=, >, >=) are read from left to right (and have the same precedence) as you can see here: Operator precedence. Therefore
a < b
is evaluated first. The result of this evaluation (true or false then) will take part in the next evaluation
(1 or 0) < c
Essentially your code is the same as
if ((a<b)<c)
The < operator has left-to-right associativity. So your expression is parsed as follows:
(a<b)<c
So a<b is first evaluated. Since a is less that b it evaluates to true, i.e. 1. So now you have:
1<c
Since c is 4 this is also true, so the final result is 1.
The a<b statement is equal to true or 1. so we can say a<b or 1 is less than c.
printf(a<b); // result is 1
printf(1 < c) // result is true because 1 is less than 4
So this statement (a<b<c) is true
try online
#include <stdio.h>
#define max(x,y)(x)>(y)?x:y
int main() {
int i = 10;
int j = 5;
int k = 0;
k == max(i++, ++j);
printf("%d%d%d ", i, j, k);
return 0;
}
I know the answer. It is 11 7 0 but how? please help me with the execution of the ternary operator.
The statement
k==max(i++,++j);
is expanded to
k==(i++)>(j++)?i++:j++;
Note that == has higher precedence than ?: operator and therefore the above expression is equivalent to
( k == ((i++)>(j++)) )?i++:j++;
Since (i++)>(j++) will be true, therefore k == ((i++)>(j++)) is evaluated as false and hence j++ (and it's value become 7) will be evaluated (i++ will be skipped).
NOTE: The above expression does not invoke undefined behavior because there exists sequence point between the evaluation of the first operand of the ternary operator and the second or third operand. For example, the expression
a = (*p++) ? (*p++) : 0
has well defined behavior.
This question is definitely a trick question that will catch many unsuspecting C programmers. The different responders here have more than 100 years of compounded experience in C, yet it took several tries to get this right:
The expression k == max(i++, ++j); expands to:
k == (i++)>(++j)?i++:++j;
Which is parsed as this (== has lower precedence than >, but higher precedence than ?):
(k == ((i++) > (++j)))
? i++
: ++j;
The ternary operator evaluates the test (i++)>(++j), which is true for the values in the program, hence evaluates to 1, different from the value of k, so it proceeds to evaluate the third expression j++, which increments j a second time and returns the intermediary value 6. There is a sequence point between the test and the branch that is executed, so it is OK to increment j twice. The second branch is not executed at all since the test evaluated to false.
i is incremented once, its value becomes 11.
j is incremented twice, its value is 7.
k is not modified by the above statement, because == is the comparison operator, not the assignment operator.
Hence the output is 11 7 0
Notes:
The program uses a macro max that evaluates its arguments more than once and they are not properly parenthesized in the expansion: 2 errors that illustrate the shortcomings of macros. This macro should be names MAX to emphasize the fact that its arguments should not have side effects and its expansion should be fully parenthesized this way:
#define MAX(x,y) ((x) > (y) ? (x) : (y))
A better alternative is to make it an inline function:
static inline int max(int x, int y) {
return x > y ? x : y;
}
If the program had this statement:
k = max(i++, ++j);
The output would be 12 6 11 because unlike ==, = has lower precedence than ? so the statement would expand to:
k = ((i++) > (++j))
? i++
: ++j;
You can study the table of operator precedence for C. There are in my humble opinion too many levels and it is very difficult to memorize all of them, especially since some of them are rather counter-intuitive: print a copy and keep it handy or make a bookmark. When in doubt, use parentheses.
You're using a double equal sign, which is a comparison. k==max(i++,++j); compares the return value of max to k, which is 0.
Instead, try changing the == to =.
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
Output of the following program is : 3 1 3
int main()
{
int a = 0, b = 1, c = 3;
*((a) ? &b : &a) = a ? b : c; // Couldn't understand expression
printf("%d %d %d \n", a, b, c);
return 0;
}
How ternary operator is working here for this output?
*( (a) ? &b : &a) = a ? b : c ;
^ ^
= 0 = 0
==false ==false
so the above expression:
*( &a) = c ;
that is:
a = c ;
because c = 3;, so it give:
a = 3 ;
b is 1 and c is 3 in your declaration(remains unchanged).
My C is a little weak, so if I'm off-base here, someone let me know.
Assuming you're talking about the expression *((a) ? &b : &a) (and that you know how the ternary operator works generally), here's how it breaks down:
The condition (a) is evaluated: when using an int in a boolean, 0 evaluates to false, while positive (or non-zero?) values evaluate to true โ in this case, a == 0 is false.
The ternary then returns the value &b if true and &a if false (in this case it's false, so it returns &a).
The value thus returned is a reference to a variable; the asterisk before the surrounding parentheses dereferences this reference, so the expression *((a) ? &b : &a) evaluates to the variable โ but not the value of โ a (if a where not 0, the expression would evaluate to b).
That line then assigns to this variable (in this case a) the value of the second ternary expression, which I assume you can figure out.
The final effect is that it assigns the value of c to the variable a, which explains the output.
Note that the ternary conditional operator has higher precedence than the assignment operator. The ternary conditional has the form:
condition ? true-result : false-result
If condition is true, the result is true-result, otherwise the result is false-result. The operator is short-circuiting in the sense that only one of the results is ever evaluated.
This operator can be used for conditional assignment. For example:
int days_of_year = is_leap_year ? 366 : 365;
The result of the ternary conditional is an r-value. This means that the result is a value that cannot be the target of an assignment. However, there is a trick that can be used to use the ternary conditional with pointers and dereference so as to get the behavior of conditionally assigning to one variable or another.
int x;
int y;
*(need_x ? &x : &y) = 0;
While the result of a ternary condition is an r-value, the result of a dereference is an l-value. This means the result of the dereference can be used as the target of an assignment.
Your code uses both of these ideas in combination.