Search

7.7 — Intro to loops and while statements

Introduction to loops

And now the real fun begins -- in the next set of lessons, we’ll cover loops. Loops are control flow constructs that allow a piece of code to execute repeatedly until some condition is met. Loops add a significant amount of flexibility into your programming toolkit, allowing you to do many things that would otherwise be difficult.

For example, let’s say you wanted to print all the numbers between 1 and 10. Without loops, you might try something like this:

While that’s doable, it becomes increasingly less so as you want to print more numbers: what if you wanted to print all the numbers between 1 and 1000? That would be quite a bit of typing! But such a program is writable in this way because we know at compile time how many numbers we want to print.

Now, let’s change the parameters a bit. What if we wanted to ask the user to enter a number and then print all the numbers between 1 and the number the user entered? The number the user will enter isn’t knowable at compile-time. So how might we go about solving this?

While statements

The while statement (also called a while loop) is the simplest of the three loop types that C++ provides, and it has a definition very similar to that of an if statement:

while (condition)
    statement;

A while statement is declared using the while keyword. When a while statement is executed, the condition is evaluated. If the condition evaluates to true, the associated statement executes.

However, unlike an if statement, once the statement has finished executing, control returns to the top of the while statement and the process is repeated. This means a while statement will keep looping for as long as the condition evaluates to true.

Let’s take a look at a simple while loop that prints all the numbers from 1 to 10:

This outputs:

1 2 3 4 5 6 7 8 9 10 done!

Let’s take a closer look at what this program is doing. First, count is initialized to 1, which is the first number we’ll print. The condition count <= 10 is true, so the statement executes. In this case, our statement is a block, so all the statements in the block will execute. The first statement in the block prints 1 and a space, and the second increments count to 2. Control now return back to the top of the while statement, and the condition is evaluated again. 2 <= 10 evaluates to true, so the code block is executed again. The loop will repeatedly execute until count is 11, at which point 11 <= 10 will evaluate to false, and the statement associated with the loop will be skipped. At this point, the loop is done.

While this program is a bit more code than typing all the numbers between 1 and 10, consider how easy it would be to modify the program to print all the numbers between 1 and 1000: all you'd need to do is change count <= 10 to count <= 1000.

While statements that evaluate to false initially

Note that if the condition initially evaluates to false, the associated statement will not execute at all. Consider the following program:

The condition 15 <= 10 evaluates to false, so the associated statement is skipped. The program continues, and the only thing printed is done!.

Infinite loops

On the other hand, if the expression always evaluates to true, the while loop will execute forever. This is called an infinite loop. Here is an example of an infinite loop:

Because count is never incremented in this program, count <= 10 will always be true. Consequently, the loop will never terminate, and the program will print "1 1 1 1 1"... forever.

Intentional infinite loops

We can declare an intentional infinite loop like this:

The only way to exit an infinite loop is through a return statement, a break statement, an exit statement, a goto statement, an exception being thrown, or the user killing the program.

Here's a silly example demonstrating this:

This program will continuously loop until the user enters n as input, at which point the if statement will evaluate to true and the associated return 0; will cause function main() to exit, terminating the program.

It is common to see this kind of loop in web server applications that run continuously and service web requests.

Best practice

Favor while(true) for intentional infinite loops.

Loop variables

Often, we want a loop to execute a certain number of times. To do this, it is common to use a loop variable, often called a counter. A loop variable is an integer that used to count how many times a loop has executed. In the examples above, the variable count is a loop variable.

Loop variables are often given simple names, such as i, j, or k. However, if you want to know where in your program a loop variable is used, and you use the search function on i, j, or k, the search function will return half your program! For this reason, some developer prefer loop variable names like iii, jjj, or kkk. Because these names are more unique, this makes searching for loop variables much easier, and helps them stand out as loop variables. An even better idea is to use "real" variable names, such as count, or a name that gives more detail about what you're counting (e.g. userCount).

Loop variables should be signed

Loop variables should almost always be signed, as unsigned integers can lead to unexpected issues. Consider the following code:

Take a look at the above example and see if you can spot the error. It's not very obvious.

It turns out, this program is an infinite loop. It starts out by printing 10 9 8 7 6 5 4 3 2 1 blastoff! as desired, but then goes off the rails, and starts counting down from 4294967295. Why? Because the loop condition count >= 0 will never be false! When count is 0, 0 >= 0 is true. Then --count is executed, and count wraps around back to 4294967295 (Assuming 32-bit integers). And since 4294967295 >= 0 is true, the program continues. Because count is unsigned, it can never be negative, and because it can never be negative, the loop won't terminate.

Best practice

Loop variables should be of type (signed) int.

Doing something every N iterations

Each time a loop executes, it is called an iteration.

Often, we want to do something every 2nd, 3rd, or 4th iteration, such as print a newline. This can easily be done by using the modulus operator on our counter:

This program produces the result:

01 02 03 04 05 06 07 08 09 10
11 12 13 14 15 16 17 18 19 20
21 22 23 24 25 26 27 28 29 30
31 32 33 34 35 36 37 38 39 40
41 42 43 44 45 46 47 48 49 50

Nested loops

It is also possible to nest loops inside of other loops. In the following example, the inner loop and outer loop each have their own counters. However, note that the loop expression for the inner loop makes use of the outer loop's counter as well!

This program prints:

1
1 2
1 2 3
1 2 3 4
1 2 3 4 5

Quiz time

Question #1


In the above program, why is variable inner declared inside the while block instead of immediately following the declaration of outer?

Show Solution

Question #2


Write a program that prints out the letters a through z along with their ASCII codes. Hint: to print characters as integers, you have to use a static_cast.

Show Solution

Question #3


Invert the nested loops example so it prints the following:

5 4 3 2 1
4 3 2 1
3 2 1
2 1
1

Show Solution

Question #4


Now make the numbers print like this:

        1
      2 1
    3 2 1
  4 3 2 1
5 4 3 2 1

Hint: Figure out how to make it print like this first:

X X X X 1
X X X 2 1
X X 3 2 1
X 4 3 2 1
5 4 3 2 1

Show Solution


7.8 -- Do while statements
Index
7.6 -- Goto statements

74 comments to 7.7 — Intro to loops and while statements

  • Fluke

    In the solution 2 answer:
    jjj is declared inside the while block so that it is recreated (and reinitialized to 1) each time the outer loop executes. If jjj were declared before the outer while loop, it's value would never be reset to 1, or we'd have to do it with an assignment statement. Furthermore, because jjj is only used inside the outer while loop block, it makes sense to declare it there. Remember, declare your variables in the smallest scope possible!

    It is okay if we follow - variables inside the scope.
    But isnt it more work for the PC to recreate jjj variable each loot (for example, if our other loop was like 10 000 times long) instead of having the jjj once declared outside and jjj = 1 inside?

  • fero45

    For conversion from letter to ASCII and back I used this and it worked:

    char ch = 'd'
    cout << ch << " " << int(ch) << endl;

    int c = 100;
    cout << c << " " << char(c) << endl;

    Is there anything wrong in this int(char) / char(int) so that we have to use static_cast(char) ?

    Fero

  • iammfa

    There is error in code number 2 line 5:
    i++; it must be iii++;

  • Matthew

    Instead of doing:

    static_cast<int>(chValue)

    I did:

    (int)chValue

    It compiled and worked fine. It seems easier than the static_cast code. Is that bad coding/is there a reason why it shouldn't be done like that?

    Thanks

    • Quinn

      (int)chValue is a C-style cast, whereas static_cast<int>(chvalue) is a C++ style one, and they are different in the fact that C-style casts are less type safe than C++ ones. Because of this, it is always suggested that you do, and get into the habit of doing, static_cast instead of C-style casts. Alex talked about this in lesson 4.4.

  • CSESTUDENT
    #include<iostream>
    int main()
    {
        using namespace std;
        char chValue=97;
        while (chValue<=122)
        {    cout << static_cast<char>(chValue) << " " << static_cast<int>(chValue) << endl;
             chValue=chValue++;
        }
    }
    

    Is it acceptable to write the quiz question in this way?

    • Quinn

      It's acceptable and will compile, but for readability it's a bit ambiguous. It may not be plainly obvious what is meant by 97 and 122.

      I also believe static_cast<char>(chValue) is unnecessary, it should just be chValue.

  • Mohamad

    I rerote the code from the first example to request an integer from the user and then add each number to the next number on the row and give the combined sum of the row.

    #include <iostream>
    
    using namespace std;
    
    int main()
    {
        
    int iii=1;
    int holder2;
    cout << "Enter the number you want to add up to: ";
    int iterations;
    cin >> iterations;
        // loop between iii and iterations
    while (iii<=iterations)    //while iii is less than or equal to iterations do the following:
    {
        // loop between 1 and iii-1
        int jjj = 1;
        int holder;
        int total=0;
        int finaltotal=0;
        while (jjj < iii)
        {
            holder=jjj;
            total=total + holder;
            cout << holder << " + ";
            jjj++;                  //increment jjj by 1
        }
    
            holder2=total;
            finaltotal=holder2+jjj;
            cout << jjj;
            cout << " = " << finaltotal;
    
        // print a newline at the end of each row
        cout << endl;
        iii++;
    }
    
    
    
    return(0);
    }
     

    The resulting output for 5 iterations is:
    Enter the number you want to add up to: 5
    1 = 1
    1 + 2 = 3
    1 + 2 + 3 = 6
    1 + 2 + 3 + 4 = 10
    1 + 2 + 3 + 4 + 5 = 15

    Not sure but If I'm right, but I think this is a fibonacci sequence. (please correct me if I'm wrong)
    It took a while to figure out the logic (and I sure this is probably not the most efficient solution, but it works)... sorry for the lack of comments... I'm gonna go back and comment more. Great Tutorial... I finally feel like I'm getting somewhere.

  • Hero Doug

    Even though it'll never be executed, there is a slight bug in the code from the second example.

    i++ should be iii++

    int iii = 15;
    while (iii < 10)
        {
        cout << iii << " ";
        i++
        }
    cout << "done!";
    
  • how do i revert the last program?
    that will print
    * * * * *
    * * * *
    * * *
    * *
    *
    please answer my question asap...
    thanks...
    • Noha
       int iii=5;
      	while (iii>=0)
      	{
      		// loop between 1 and iii
      		int jjj = 1;
      		while (jjj <= iii)
      		{
      			cout << "*" ;
      			jjj++;
      		}
      
      		// print a newline at the end of each row
      		cout << endl;
      		iii--;
      	}

      notice what i changed in the given example...

      • how do i get the previous code to read this?
        12345
        1234
        123
        12
        1

        pliz reply asap!!!

        • Elpidius

          This program prints:

          1 2 3 4 5
          1 2 3 4
          1 2 3
          1 2
          1

          I hope this helps.

    • Canute
      I don't know I'm sure this is way late but here if this helps.
      
      
      // Loop between 1 and 5
      int iii=1;
      while (iii<=5)
      {
          // loop between 1 and iii
          int jjj = 5;//I flipped 1 to 5 so it starts from bottom up
          while (jjj >= iii)// Flipped <= to >=, if not it would not loop
              cout << jjj--;//Flipped the minus to so it gets smaller, if not it would be infinite
      
          // print a newline at the end of each row
          cout << endl;
          iii++;
      }
      
  • Cameron

    Why does the last program print

    1
    1 2
    1 2 3
    1 2 3 4
    1 2 3 4 5

    Instead of

    1
    2
    3
    4
    5

    ? Am I missing something? It seems to only print one number each time it repeats by looking at the code.

    • This happens because there is a loop inside of a loop.

      The outer loop iterates iii from 1 to 5. The inner loop iterates jjj from 1 to iii.

      Each time the outer loop iterates, all of the inner loop iterations are restarted.

      So the first time, iii = 1 and jjj = 1. The inner loop executes once and prints 1.
      The second iteration, iii = 2 and jjj = 1. The inner loop executes twice and prints 1 2.
      The third iteration, iii=3 and jjj = 1. The inner loop executes three times and prints 1 2 3.
      And so on.

  • Allen01

    In the code above, shouldn't the if statement read:

     if (iii % 10 == 0)  

    [ Yes, it should. Thanks for catching that. -Alex ]

Leave a Reply

You can use these HTML tags

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code class="" title="" data-url=""> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong> <pre class="" title="" data-url=""> <span class="" title="" data-url="">