#include <stdio.h> int main(void){ int a = 1, b = 2, c = 3; double x = 1.0; int res1, res2, res3, res4; int res1_equiv, res2_equiv, res3_equiv, res4_equiv; res1 = a > b && c < x; res2 = a < ! b || ! ! a; res3 = a + b < ! c + c; res4 = a - x || b * c && b / a; printf("res1 = %d, res2 = %d, res3 = %d, res4 = %d \n", res1, res2, res3, res4); res1_equiv = (a > b) && (c < x); res2_equiv = (a < (! b)) || (! (! a)); res3_equiv = (a + b) < ((! c) + c); res4_equiv = (a - x) || ((b * c) && (b / a)); printf("res1 = %d, res2 = %d, res3 = %d, res4 = %d \n", res1_equiv, res2_equiv, res3_equiv, res4_equiv); }
![]() | res1 = a > b && c < x; res2 = a < ! b || ! ! a; res3 = a + b < ! c + c; res4 = a - x || b * c && b / a; |
These are program lines corresponding to the four expressions in exercise 2 at page 115 of C by Dissection. In the following we show and explain equivalent expressions, each assigned to a variable such that we easily can print and control the results. |
![]() | res1_equiv = (a > b) && (c < x); |
This shows a fully parenthesized version of the first expression. We first notice that we are dealing with a short circuit expression. First the left operand (a > b) of && is evaluated to false (0) because a is 1 and b is 2. Without calculating the expression (c < x) it can be concluded, that value of the entire expression is 0. |
![]() | res2_equiv = (a < (! b)) || (! (! a)); |
We notice again that we are dealing with a short circuit expression, because of ||. First (! b) is calulated. It means not b. The value is 0, because b is 2 (which represents true). Then (a < (! b)) is calculated. It is equivalent to 1 < 0, which is false; Therefore the concrete value is 0. We need to calculated the right operand of || because the entire expression may still end up being true (1). The inner (! a) is 0 because a is 1. Therefore (! (! a)) is 1. Thus, the value of the entire expression is true (1). |
![]() | res3_equiv = (a + b) < ((! c) + c); |
Due to the operator precedence rules, the subexpression (! c) is evaluated first. It means not c. The value is 0, meaning false because c is 3 (true). The expression (a + b) is evaluated to 3. Then ((! c) + c) is evaluated, which can be reduced to (0 + 3) which, of course, is 3. The value of the entire expression is the same as 3 < 3, which is false, or concretely 0. |
![]() | res4_equiv = (a - x) || ((b * c) && (b / a)); |
We first notice that we are dealing with a short circuit expression again, because of ||. The left operand (a - x) is evaluted to 0.0 (false), and therefore there is still a chance for the entire expression to be both true or false. In other words, we need to caluculate ((b * c) && (b / a)). It is a new short circuit expression because of &&. The left operand (b * c) is evaluted to true (6). Therefore the right operand of && is evaluted too, because the left operand alone does not allow us to determine the value of ((b * c) && (b / a)). It is the expression (b / a), the value of which is true (2). Therefore the value of ((b * c) && (b / a)) is true (1). At the outer level false || true is true (1). |
![]() | printf("res1 = %d, res2 = %d, res3 = %d, res4 = %d \n", res1_equiv, res2_equiv, res3_equiv, res4_equiv); |
The printf command prints the values of the variables assigned above: res1 = 0, res2 = 1, res3 = 0, res4 = 1 |