Home > Back-end >  Understanding the math of loops in C
Understanding the math of loops in C

Time:02-19

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);
  1. First, we execute the initialization statement, which gives us a=1 and b=1 (b was set earlier in the code).

  2. We execute the test expression (a < b 4, which is 1 < 1 4), which is true, so we continue

  3. We execute the loop body. We haven't performed any operations on a yet, so a is still equal to 1 so our output is:

    1
    
  4. Now execute the update expression, b , a = b * 2. This increments b (giving us b=2), and then sets a = b * 2, so a = 4.

  5. We execute the test expression, and 4 < 2 4, so we continue.

  6. We execute the loop body, which gives us as output:

    4
    
  7. We execute the update expression. We increment b, giving us b=3, and then set a = b * 2, giving us a = 6.

  8. We execute the test expression, and 6 < 3 4, so we continue.

  9. We execute the loop body, giving us as output:

    6
    
  10. We execute the update expression. We increment b, giving us b=4, and then set a = b * 2, giving us a = 8.

  11. 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);
  1. b is set to 1;
  2. a is set to 1;
  3. a (1) is less than b 4 (5), so the loop executes the printf(), printing 1;
  4. b is incremented to 2; a is set to 4 (b * 2);
  5. a (4) is less than b 4 (6), so the loop executes the printf(), printing 4;
  6. b is incremented to 3; a is set to 6 (b * 2);
  7. a (6) is less than b 4 (7), so the loop executes the printf(), printing 6;
  8. b is incremented to 4; a is set to 8 (b * 2);
  9. a (8) is not less than b 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);
  1. a is set to 5;
  2. b is set to 0;
  3. a (5) is greater than 3 so the loop body executes;
  4. b (0) has a (5) added to it, so it becomes 5;
  5. a is decremented, so it becomes 4;
  6. a (4) is greater than 3 so the loop body executes;
  7. b (5) has a (4) added to it, so it becomes 9;
  8. a is decremented, so it becomes 3;
  9. a (3) is not greater than 3 so the loop terminates;
  10. The printf() statement prints a then b, so the result is 3, 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);
  1. a is set to 7;
  2. b is set to 2;
  3. b (2) is less than a (7), so the loop executes the assignment operator;
  4. a - 2 is 5 so b is set to 7 (2 5);
  5. a is incremented to 8;
  6. b (7) is less than a (8), so the loop executes the assignment operator;
  7. a - 2 is 6, so b is set to 13 (7 6);
  8. a is incremented to 9;
  9. b (13) is not less than a (9), so the loop terminates;
  10. The printf() statement prints b then a, so the result is 13, 9.
  •  Tags:  
  • c
  • Related