I have these three codes, which do work, but they're not printing what I expected them to print. I don't think I properly understand the math/precedence here and was wondering if someone could help me comprehend.
CODE A
int a;
int b = 1;
for (a = 1; a < b 4; b , a = b * 2)
printf("%i\n", a);
I expected it to print out 4, 5. but it's 3, 9. I understand that's correct -- but why?
CODE B.
int a = 5;
int b = 0;
while (a > 3)
{
b = a;
--a;
}
printf("%i, %i\n", a, b);
Admittedly I struggled figuring out the math. It prints out 3, 9 --- but I don't get why.
CODE C.
int a;
int b;
for (a = 7, b = 2; b < a; a )
b = a - 2;
printf("%d, %d\n", b, a);
This prints out 13, 9 but I got 11, 7.
CodePudding user response:
Let's step through the first loop:
for (a = 1; a < b 4; b , a = b * 2)
printf("%i\n", a);
First, we execute the initialization statement, which gives us
a=1
andb=1
(b
was set earlier in the code).We execute the test expression (
a < b 4
, which is1 < 1 4
), which is true, so we continueWe execute the loop body. We haven't performed any operations on
a
yet, soa
is still equal to1
so our output is:1
Now execute the update expression,
b , a = b * 2
. This incrementsb
(giving usb=2
), and then setsa = b * 2
, soa = 4
.We execute the test expression, and
4 < 2 4
, so we continue.We execute the loop body, which gives us as output:
4
We execute the update expression. We increment
b
, giving usb=3
, and then seta = b * 2
, giving usa = 6
.We execute the test expression, and
6 < 3 4
, so we continue.We execute the loop body, giving us as output:
6
We execute the update expression. We increment
b
, giving usb=4
, and then seta = b * 2
, giving usa = 8
.We execute the test expression.
8 < 4 4
is false, so we exit the loop.
You can walk through a similar process for the other loops.
CodePudding user response:
What might be part of the source of confusion is that a for loop in c will execute until the first semicolon found in the source code if there is not a surrounding pair { ... }
to delineate several lines of code. For code A, the stuff after the second semicolon in the for loop is executed on every iteration and the printf
statement is executed on every iteration too. In the last code snippet, code C. The printf
is only executed after all the iterations of the for loop have completed. The same is true of the while loop in code snippet B, the printf
executes after the while
terminates. The while loop use of {...}
delimiting characters makes this more obvious to the reader while the for loops do not.
Of course you still need to work through the calculations themselves too-which are also fairly tricky.
CodePudding user response:
A for
loop consists of the following structure:
for ( init; condition; increment ) {
statement(s);
}
As for how this actually executes, it is exactly equivalent to the following:
init;
while(condition) {
statement(s);
increment;
}
So, if we have the following code (CODE A):
int a;
int b = 1;
for (a = 1; a < b 4; b , a = b * 2)
printf("%i\n", a);
That means:
init: a = 1
condition: a < b 4
increment: b , a = b * 2
statement(s): printf("%i\n", a);
We can translate that into a while
loop by substituting:
int a;
int b=1;
a = 1;
while(a < b 4) {
printf("%i\n", a);
b , a = b * 2;
}
Now, we can trace the execution step by step to see what's happening.
First loop:
1. b=1
2. a=1
3. a < b 4
1 < 1 4
1 < 5
true
4. Output: 1
5. b
b = b 1
= 1 1
= 2
6. a = b*2
= 2*2
= 4
Second loop:
1. a < b 4
4 < 2 4
4 < 6
true
2. Output: 4
3. b
b = b 1
= 2 1
= 3
4. a = b*2
= 3*2
= 6
Third loop:
1. a < b 4
6 < 3 4
6 < 7
true
2. Output: 6
3. b
b = b 1
= 3 1
= 4
4. a = b*2
= 4*2
= 8
Fourth loop:
1. a < b 4
8 < 4 4
8 < 8
false
2. End
CodePudding user response:
Looking at Code A:
int a;
int b = 1;
for (a = 1; a < b 4; b , a = b * 2)
printf("%i\n", a);
b
is set to1
;a
is set to1
;a
(1
) is less thanb 4
(5
), so the loop executes theprintf()
, printing1
;b
is incremented to2
;a
is set to4
(b * 2
);a
(4
) is less thanb 4
(6
), so the loop executes theprintf()
, printing4
;b
is incremented to3
;a
is set to6
(b * 2
);a
(6
) is less thanb 4
(7
), so the loop executes theprintf()
, printing6
;b
is incremented to4
;a
is set to8
(b * 2
);a
(8
) is not less thanb 4
(8
too), so the loop terminates.
You can apply a similar technique to the other cases.
Looking at Code B:
int a = 5;
int b = 0;
while (a > 3)
{
b = a;
--a;
}
printf("%i, %i\n", a, b);
a
is set to5
;b
is set to0
;a
(5
) is greater than3
so the loop body executes;b
(0
) hasa
(5
) added to it, so it becomes5
;a
is decremented, so it becomes4
;a
(4
) is greater than3
so the loop body executes;b
(5
) hasa
(4
) added to it, so it becomes9
;a
is decremented, so it becomes3
;a
(3
) is not greater than3
so the loop terminates;- The
printf()
statement printsa
thenb
, so the result is3, 9
.
Looking at Code C:
int a;
int b;
for (a = 7, b = 2; b < a; a )
b = a - 2;
printf("%d, %d\n", b, a);
a
is set to7
;b
is set to2
;b
(2
) is less thana
(7
), so the loop executes the assignment operator;a - 2
is5
sob
is set to7
(2 5
);a
is incremented to8
;b
(7
) is less thana
(8
), so the loop executes the assignment operator;a - 2
is6
, sob
is set to13
(7 6
);a
is incremented to9
;b
(13
) is not less thana
(9
), so the loop terminates;- The
printf()
statement printsb
thena
, so the result is13, 9
.