newinc
newinc

Reputation: 1

Nested for-loop: why is the condition stated in for() ineffective?

So for the code below, I want the C program to show odd numbers (that are not multiples of 3) between 1 and 999, with 9 in one line.

1   5   7   11   13   17   19   23   25

29   31   .. and so on.

Below is the code that I used. While I did figure out how to make it work - the if (i >=999) break; line helped, I don't understand why i goes over 999 if that break line didn't exist. In other words, the condition i < 999 in both loops is ineffective.

Could someone help me understand why this acts this way?

I'm using Microsoft Visual Studio 2005 in class.

#include <stdio.h>

void main(void)
{
    int i, j;

    for(i = 1; i < 999; i++)
    {
        for(j = 0; i < 999, j< 9; i++, j++)
        {
            if (i%2 == 0 || i%3 == 0) {
                j = j-1;
                if (i >=999) break;
                continue;
            }
            printf("%-3d ", i);
            if (j == 8) break;
        }
        printf("\n");
    }
}

Upvotes: 0

Views: 167

Answers (5)

Michael Burr
Michael Burr

Reputation: 340178

The condition in your inner for loop:

for(j = 0; i < 999, j< 9; i++, j++) {
    // ...
}

Is i < 999, j< 9 which uses the often misunderstood comma operator. The way that expression gets evaluated is:

  • i < 999 is evaluated, then the result is ignored (effectively, this part of the expression is a nop since there are no side effects)
  • j < 9 is evaluated and that is the result of the expression

If you want to use both condition in the expression, you want to use the logical And operator:

 i < 999 && j < 9

However, since i isn't modified in the inner loop, there's no reason to check it in that loop's condition - the outer loop will prevent the inner loop from being executed when i < 999 fails.

Upvotes: 0

Thirupathi Thangavel
Thirupathi Thangavel

Reputation: 2465

The problem is in the condition of the for loop. There are two conditions i < 999, j < 9.

But it checks for only the last condition.

You want to change it to for(j = 0; i < 999 && j< 9; i++, j++) to check for both conditions

Upvotes: 0

user2736738
user2736738

Reputation: 30906

An easy way is to

int numbers_in_line=0;
for(int i=1;i<=999;i++)
{
   if(i%2 && i%3) // not divisible by 2 as well as 3.
   {
      printf("%d ",i);
      numbers_in_line++;       // printed one number more
      if(numbers_in_line==9) 
      {
         printf("\n");
         numbers_in_line=0;  //reset for next line
      }
   }
}

In your code you can easily use a count variable to remember how many number you printed. That's it.

One thing in if(i%2==0 || i%3==0) now if for i=6 it will print it but it shouldn't. Clearly make it if(i%2!=0 && i%3!=0)

Another thing from your code there are few things clear,

  1. Know how `,` works.(As mentioned in other answers)
  2. Use simple logic not the negation of it..(The if mentioned)
  3. Why are you keep decreasing as well increasing j. It's sole purpose is to keep track of number you have put in a line. So either decrease / increase it then reset to 9/0 as per your requirement respectively. Think this way you are never removing a number you have printed in a line so why decrease?

Upvotes: 1

surajs1n
surajs1n

Reputation: 1583

Consider the expression carefully. i < 999 , j < 9 . Here, first i < 999 will get evaluated and after that j < 9. But, the result of the whole expression will be result of j < 9 alone. Look at the code snippet for more clarification:

#include <stdio.h>

int main()
{
    int flag = (0,0);
    printf("%i ",flag);

    flag = (0,1);
    printf("%i ",flag);

    flag = (1,0);
    printf("%i ",flag);

    flag = (1,1);
    printf("%i ",flag);
}

Output: 0 1 0 1

And as mentioned in your code, if the value of i = 999, then the value of j comes out as -1, which becomes 0 on next iteration and similarly the value of i get increased by one. Therefore, the result of i < 999 comes as 0 or false and of j < 9 comes as 1 or true.

Since, the original expression was i < 999 , j < 9, which becomes 0,1 and from the above code we can see, it returns 1 or true, which result it to further carry out the iterations.

Upvotes: 0

Tim Biegeleisen
Tim Biegeleisen

Reputation: 520898

Because you original code was a bit convoluted, I thought it would be easiest to answer your question by starting from scratch. Here is a C code which achieves what you want, and it is a lot simpler than the OP:

void main(void) {
    int counter = 0;

    for (int i=0; i < 1000; ++i) {
        if (i % 2 != 0 && i % 3 != 0) {  // if not even (i.e. odd) AND not divisible by 3
            if (counter == 9) {          // start a new line for each 9 numbers
                printf("\n");
                counter = 0;             // reset the counter
            }
            printf("%-3d ", i);
            ++counter;                   // increment counter for each new number
        }
    }
}

I don't think you need or should have a double for loop in the solution. And the conditions you have in the for loops also appear very complex. This solution makes one pass over all numbers between 0 and 999 and generates the desired output.

Upvotes: 1

Related Questions