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.
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
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.
I tried running the following code in C:
#include <stdio.h>
int main() {
int a = 10, b = 5, c = 5;
int d;
d = b + c == a;
printf("%d", d);
}
I got the output as d = 1. Can someone please explain to me what happens when we use == like this?
§6.5.9 (== and !=)-http://c0x.coding-guidelines.com/6.5.9.html
The == (equal to) and != (not equal to) operators are analogous to the relational operators except for their lower precedence.)Each of the operators yields 1 if the specified relation is true and 0 if it is false. The result has type int.
For any pair of operands, exactly one of the relations is true.
So here as b+c is equal to a as both has value 10 therefore it yields 1.
Because b + c is executed first, and after is evaluate comparison with == operator.
In c, addition has higher precedence than ==, so it adds b and c before comparing the result to a, since it is true it results in 1, if it was false it would result in 0.
== is the equal-to operator. It returns 1 if the two sides are equal and 0 otherwise.
int main() {
int x=1;
int a=2;
int b=3;
if(a++>2 && --b<3)
x=5;
printf("%d %d %d",a,b,x);
}
Shouldn't this code return 3 2 5 respectively, instead of 3 3 1?
a++>2
will return false, since 2 is not greater than 2 (remember, a++ means the old value of a will be returned, not the incremented value). Also, ais now worth 3.
Since the && operator is short-circuiting, the --b<3 part will not be evaluated, so b is still worth 3.
The variable x remains unchanged because the conditional was false.
So you do get "3 3 1"
a++>2 is false, and because of short-circuiting, --b<3 is never evaluated. a++>2 is false because a is initially 2, and 2 is not greater than 2. As a side effect, though, a has become 3. Because the condition was false, x is unchanged. Thus the final values of b and x are the same as their initial values, while a has been incremented.
No. Your code explained:
if(a++>2) // a = 2, so 2 > 2? No.
// So the other condition WILL NOT be checked (--b>3), because it's an && condition.
But, a++ increments the 'a', AFTER the expression. So now:
a = 3
b = 3
The code doesn't enter into the if block. So 'x' will never be changed. Then:
a = 3
b = 3
x = 1
If you did:
if(++a>2 ...
The ++a increments BEFORE the expression. So 'a' would be 3 and the if would check '3 > 2'.
The post-increment will be resolved first, then the comparation. That is because of the Operator Precedence Rules.
If you have two operator with different priority, the one with the greater priority will be invoked first, then the other one. If two operator have the same priority, they will be solved according to the corresponding associativity rule.
You can check operators priority and associativity rules in the next link:
http://en.cppreference.com/w/c/language/operator_precedence
i) What does if(0) mean?
Everytime I use it to test what output i will get, it returns the false part.
Is it equivalent to if(0 == 0), incase of which the true part is evaluated.
ii) Associativity of logical NOT ! is right to left.
Link: http://www.liv.ac.uk/HPC/HTMLF90Course/HTMLF90CourseNotesnode94.html
The second example in the link of logical operators:
But as per the line "the two subexpressions containing the monadic .NOT. are effectively evaluated first, as there are two of these the leftmost, .NOT.A is done first followed by .NOT.E.", the left NOT is evaluated first, but the first one to be evaluated should be the one on the right...???
I) In C, 0 is false and everything else is true. So with if (0), the condition will always be false and the body will never be executed because 0 is always false.
if (0 == 0) is completely different because 0 does in fact equal zero, and the expression 0 == 0 evaluates to true, so the body of the if is executed.
II) The associativity of operators determines what happens when you have ambiguities from multiple operators of the same precedence. For instance, what should happen in a - b - c? Should the b - c be evaluated first or the a - b? It does matter what order you do them in, because if a = 1, b = 2, and c = 3, a - (b - c) is 2, but (a - b) - c is -4. But because subtraction is left-associative, we can know that a - b will be evaluated first, so the answer to a - b - c is -4 when a = 1, b = 2, c = 3.
All that being said, I can't think of a case where the associativity of the logical not operator would matter, and the associativity of an operator does not determine what order it will be executed in when it is seperated by operators of different precedence.
i) in C, 0 mean false, so if(0) will always jump to the else (if there).
it is the opposite of if(0==0), (or simply if(1)), which will do the true part.
if (0) evaluates the predicate 0 as a binary value. Binary values in C use integers, where zero means false and non-zero means true. Therefore, 0 will always evaluate to false.
For binary operators, being right- or left-associative determines the order that otherwise equally important operators will be processed. Consider the subtraction operator:
37 - 10 - 4
Both - are equal precedence so which should we evaluate first? Well, - is left-associative so we do:
(37 - 10) - 4 ==> (27) - 4 ==> 23
If the - operator were right-associative, we would do:
37 - (10 - 4) ==> 37 - 6 ==> 31
Equality (=) is right-associative because we might chain equalities together. So, if we see
// a and b are initialized to 0
a = b = 45
Both = are equal precedence so we evaluate right to left and do:
a = (b = 45) // b receives 45
a = 45 // a receives 45
If we were to go left-right, we'd get an unexpected result:
(a = b) = 45 // a receives 0
b = 45 // b receives 45
For unary operators, however, ordering can only matter when multiple unary operators affect the same value. For example, let's do:
char x = 0xFF
bool y = !~x
These unary operators are right-associative, so we do:
!(~0xFF) ==> !(0x0) ==> true
In the example you showed, the negation operators affecting A and E didn't have "equal precedence" because they didn't have the same operand. So, associativity doesn't apply.