'Understanding the math of loops in C
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.
Solution 1:[1]
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=1andb=1(bwas 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
ayet, soais still equal to1so our output is:1Now 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:
4We 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:
6We 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 + 4is false, so we exit the loop.
You can walk through a similar process for the other loops.
Solution 2:[2]
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.
Solution 3:[3]
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
Solution 4:[4]
Looking at Code A:
int a;
int b = 1;
for (a = 1; a < b + 4; b++, a = b * 2)
printf("%i\n", a);
bis set to1;ais set to1;a(1) is less thanb + 4(5), so the loop executes theprintf(), printing1;bis incremented to2;ais set to4(b * 2);a(4) is less thanb + 4(6), so the loop executes theprintf(), printing4;bis incremented to3;ais set to6(b * 2);a(6) is less thanb + 4(7), so the loop executes theprintf(), printing6;bis incremented to4;ais set to8(b * 2);a(8) is not less thanb + 4(8too), 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);
ais set to5;bis set to0;a(5) is greater than3so the loop body executes;b(0) hasa(5) added to it, so it becomes5;ais decremented, so it becomes4;a(4) is greater than3so the loop body executes;b(5) hasa(4) added to it, so it becomes9;ais decremented, so it becomes3;a(3) is not greater than3so the loop terminates;- The
printf()statement printsathenb, 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);
ais set to7;bis set to2;b(2) is less thana(7), so the loop executes the assignment operator;a - 2is5sobis set to7(2 + 5);ais incremented to8;b(7) is less thana(8), so the loop executes the assignment operator;a - 2is6, sobis set to13(7 + 6);ais incremented to9;b(13) is not less thana(9), so the loop terminates;- The
printf()statement printsbthena, so the result is13, 9.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | larsks |
| Solution 2 | Lucas Roberts |
| Solution 3 | Random Davis |
| Solution 4 |
