a+=b>=300?b=100:a==100;
If a and b are initialized to 100 and 200 respectively,
what will be the values of a and b after executing the ternary operator?
The answer was a=101, b=200.
How is this possible?
Just add some parentheses and spaces to make it more readable and it should be obvious:
a += ((b >= 300) ? (b = 100) : (a == 100));
(Refer to a C operator precedence table to see why the parentheses can be placed where they are in the above expression.)
So this is essentially just:
a += 1;
The conditional operator has nothing to do with it, basically it just adds clutter here. Your program is equivalent to a += a==100. Which gives a += 1, since the result of == is a boolean 1=true.
First add some spaces to make this statement expression easier to parse visually:
a += b >= 300 ? b = 100 : a == 100;
Then parse it according to the C grammar (which is subtly different from the java or javascript grammars in this particular case):
a +=
(b >= 300) ?
b = 100 :
a == 100
;
Since b = 200, the test b >= 300 evaluates to false and the first branch of the ternary operator is not evaluated, but the second branch is and a == 100 evaluates to 1 as a is indeed equal to 100. The result of the ternary operator, 1, is added to a, hence the new value for a is 101. b is unchanged.
Related
I'm practicing to read C-code faster but I'm struggling to understand this portion:
int a = 7, b = 3, c = 2, d;
d = (b+c >a) || a > c ? a-- : a++;
When I enter this into my program and print out integer d, I get the result of 7. But I cannot really understand why. Can somebody please explain this to me?
You are assigning to d the value of either a-- or a++. Both of these expressions have a value of 7 (the original value of a); the difference between the operators is what they do to their operand (a) after evaluating the expression: one then increments it and the other decrements it.
That is why they are called post-increment and post-decrement operators.
Maybe you are getting confused with the pre-increment and pre-decrement operators, which are ++a and --a? (See also: Pre increment vs Post increment in array .)
As for the ternary operator (x ? y : z) and how to 'read' that, then you can take it as if x then y else z; so, if the result of the test (which has a logical OR, which means it will be true if either comparison is true) is true, then d = a--, otherwise d = a++. But, as mentioned already, both will give the same value to d, in this case (though they will have different effects on a). Note also that the ternary operator has a lower precedence than either the logical OR or the relational comparisons, so you can read as though everything between the = and the ? is in (another set of) brackets.
The expression is parsed as
d = ((b+c >a) || a > c) ? a-- : a++;
so d gets the result of either a— or a++, which is 7 in both cases. The difference is what the value of a is after the expression is evaluated.
|| forces left to right evaluation, so b+c > a is evaluated first. Since b+c is 5, the result of the expression is false (0), so a > c is evaluated. The result of that expression is true (1), so the result of (b+c > a) || a > c is true (1), meaning we assign the result of a— to d. Thus d will be 7 and a will be 6.
This is how operator precedence works in C
Step 1
d = (3 + 2 > 7) || 7 > 2 ? a-- : a++;
Step 2
d = false || true ? a-- : a++;
Step 3
d = true ? a-- : a++;
Here value of 'a' will be changed but not in this statement so value of 'a' still be 7
But if you print a in other statement it will changed as 6.
To learn more about operator precedence https://en.cppreference.com/w/c/language/operator_precedence
int a = 0, b = 0, c = -1;
if (b = a || b == ++c )
a+=3;
Why are the values of a,b and c 3 , 1, 0 respectively? More specifically, why is b 1 and not 0?
Because || has higher precedence than =, so it's being parsed as if you'd written.
if (b = (a || (b == ++c)))
This calculates a || (b == ++c). This is true because b == 0 and ++c == 0, so b == ++c is true, and true is 1.
Add parentheses to get what you want:
if ((b = a) || (b == ++c))
But IMHO it's generally best to avoid writing such complex expressions. Do them as separate statements:
b = a;
if (b || b == ++c)
Once you are clear with the precedence of operators,it will be easy for you to tackle such type of questions.Go through this to know about operator precedence in C.
You should see my answer after going through the precedence list because then it will get more easily inside your mind.
Now,coming to your question....
Out of all the operators used in the above code, ++c has the highest precedence.So the value of c becomes 0 and then value of c is compared to value of b here b == ++c which evaluates to true i.e 1 and now || of 1 and a is taken which is 1.
And finally this result 1 is assigned to b.So the overall execution of if statement evaluates to true and value of a is incremented by 3.
Hence finally the value of a=3,b=1 and c=0.
I recently took an exam on C programming that provided these expressions:
int a = 3, b = 10, c = 4, d = 6;
(c >= d) || (a > b)
correction: the first expression is: (c <= d) || (a > b)
(a <= b) && (c == d)
and a question asking how many comparisons were made in each expression. I said there were three comparisons in each expression. In the first are great than or equal to, OR, and greater than. In the second is less than or equal to, AND, and equal to. But according to the grader, there's only one comparison in the first expression and two in the second.
Can anyone please explain why?
Are the integers relevant?
The integers are quite relevant to the context because of short-circuiting operators || and &&.
For || the second comparison is never made if the first expression is true.
For && the second comparison is never made if the first expression is false.
Also, the AND and OR operators themselves are not comparisons.
Given the numbers are:
int a = 3, b = 10, c = 4 , d = 6;
For the first expression (after your update):
(c <= d) || (a > b)
variable c is smaller than d (4 is smaller 6), so that whole expression turns out true whatever the value of the second part is, so that's only 1 comparison.
For the second:
(a <= b) && (c == d)
Variable a is smaller than b, but the program has to check that other part too (in case c is not equal to d and they are in fact different), so here there are also 2 comparisons.
The point of this question was to determine whether you understood the concept of short-circuiting for || and && in C. These are logical connectives, not comparisons.
In your example, you are given:
int a = 3, b = 10, c = 4, d = 6;
You are then asked how many comparisons are performed for:
1. (c <= d) || (a > b)
2. (a <= b) && (c == d)
Both of these expressions contain two comparison operations, but that does not mean those comparisons will actually be performed.
In case (1), it first compares c vs. d, using <=. The result of this is true (i.e. 1). This is all it needs to determine that the result of the || operation will be true (i.e. 1), so it skips the second comparison of (a > b), since it's not needed to obtain the final result. This is called short-circuiting.
In case (2), it first compares a vs. b using <=. The result of this is true (i.e. 1), so it proceeds to the second comparison of (c == d). The result of this is false (i.e. 0), so the final result is false (i.e. 0).
So for (1) it only needed to perform one comparison, but for (2) it needed to perform two comparisons. If the values of the variables are changed, then the number of comparisons could change as well.
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
Consider the code:
if(x = a/b, a%b)
printf("do this");
else
printf("do that");
Now if I replace if statement by if(x = a/b && a % b). Then it works also. So I want to know that replacing comma by && operator and vice-versa works always or not in if-else and loops
They are quite different!
In the first example, , is the comma operator, which is a binary operator that evaluates its first operand and discards the result, and then evaluates the second operand and returns this value (and type).
So,
if(x = a/b, a%b)
is equivalent to (thanks to #jaket)
x = a/b;
if(a%b)
a%b will always be evaluated.
For the second one:
if(x = a/b && a % b)
is equivalent to
x = (a/b) && (a%b);
if( x )
a%b will only be evaluated if a/b (i.e. a/b is not zero) is true.
if you replace the comma operator by &&, you're changing the logic slightly. What the comma operator does is it will execute x = a/b and "discard the result", i.e. it's not taken into consideration for the if's condition, only a%b is taken into account.
if you do
if(x = a/b && a % b)
then "do this" will be printed if and only if a/b is non zero and a % b is non zero. Whereas with the comma operator, "do this" is printed only if a % b is non zero.
if(x = a/b, a%b)
is an obfuscated, unreadable way of writing
x = a/b;
if(a%b)
But
x = a/b && a % b
is equivalent to
x = ( (a/b) && (a%b) );
To sum it up, don't mix a whole lot of different operators on the same line. The only thing you achieved with it was to confuse yourself, while creating bugs.
The && operator forces the the result of a/b as well into consideration in determining the expression x = a/b && a%b, In case of ,, the result of a/b is ignored. So replacing , with && will not work always. And not the right thing to do,