Search

5.5 — While statements

The while statement is the simplest of the four loops that C++ provides, and it has a definition very similar to that of an if statement:

while (expression)
    statement;

A while statement is declared using the while keyword. When a while statement is executed, the expression is evaluated. If the expression evaluates to true (non-zero), the 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.

Let’s take a look at a simple while loop. The following program prints all the numbers from 0 to 9:

This outputs:

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

Let’s take a closer look at what this program is doing. First, count is initialized to 0. 0 < 10 evaluates to true, so the statement block executes. The first statement prints 0, and the second increments count to 1. Control then returns back to the top of the while statement. 1 < 10 evaluates to true, so the code block is executed again. The code block will repeatedly execute until count is 10, at which point 10 < 10 will evaluate to false, and the loop will exit.

It is possible that a while statement executes 0 times. Consider the following program:

The condition 15 < 10 immediately evaluates to false, so the while statement is skipped. The only thing this program prints 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 "0 0 0 0 0 ..." forever.

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.

Programs that run until the user decides to stop them sometimes intentionally use an infinite loop along with a return, break, or exit statement to terminate the loop. It is common to see this kind of loop in web server applications that run continuously and service web requests.

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 variable that is declared for the sole purpose of counting 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, naming variables i, j, or k has one major problem. 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! Many words have an i, j, or k in them. Consequently, a better idea is to use iii, jjj, or kkk as your loop variable names. 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.

It is best practice to use signed integers for loop variables. Using 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 overflows back to 4294967295. And since 4294967295 is >= 0, the program continues. Because count is unsigned, it can never be negative, and because it can never be negative, the loop won't terminate.

Rule: Always use signed integers for your loop variables.

Iteration

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

Because the loop body is typically a block, and because that block is entered and exited with each iteration, any variables declared inside the loop body are created and then destroyed with each iteration. In the following example, variable x will be created and destroyed 5 times:

For fundamental variables, this is fine. For non-fundamental variables (such as structs and classes) this may cause performance issues. Consequently, you may want to consider defining non-fundamental variables before the loop. This is another one of the cases where you might declare a variable well before its first actual use.

Note that variable count is declared outside the loop. This is necessary because we need the value to persist across iterations (not be destroyed with each iteration).

Often, we want to do something every n iterations, 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 loops 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

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

Show Solution

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

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

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

5.6 -- Do while statements
Index
5.4 -- Goto statements

163 comments to 5.5 — While statements

  • Satwant

    LAST QUIZ SOLUTION

  • nikos-13

    "
    while (outer <= 5)
        {
            // loop between 1 and outer
            int inner = 1;
            while (inner <= outer)
                std::cout << inner++ << " ";

            // print a newline at the end of each row
            std::cout << "\n";
            ++outer;
        }
    "

    If we wanted to have more statements execute in the inner while, we should put them into blocks?

  • Elruin

    Is it ok to use another while for X-es or Gaps for last quiz?

  • Jonas

    Here’s my solution for Quiz #2:

    (Just recognized: c++ :P)

  • Sumit Kumar Chourasia

    #include &lt;iostream&gt;

    // Iterate through every number between 1 and 50
    int main()
    {
        int count = 1;
        while (count &lt;= 50)
        {
            // print the number (pad numbers under 10 with a leading 0 for formatting purposes)
            if (count &lt; 10)
                std::cout &lt;&lt; "0" &lt;&lt; count &lt;&lt; " ";
            else
                std::cout &lt;&lt; count &lt;&lt; " ";

            // if the loop variable is divisible by 10, print a newline
            if (count % 10 == 0)
                std::cout &lt;&lt; "\n";

            // increment the loop counter
           count++;
        }

        return 0;
    }
    Sir, here count++ and  ++count give same outputs, please explain.

    • Alex

      When used by itself in a statement, ++count and count++ have the same end-result.

      Both ++count and count++ increment count -- what differs is in how they evaluate -- ++count evaluates to (count+1), whereas count++ evaluates to (count). However, in this case, that evaluated value is discarded, and so has no impact. Only the side effect of incrementing count remains.

  • 赵杰

    I think the reason why we have a different result is changing happened in the paste process, maybe I passed the wrong one to you, but here is the correct one!

    #include"stdafx.h"
    #include<iostream>

    int main() {
        int outer = 5;
        while (outer >= 1) {
            int inner = 1;
            if (inner == outer)
            {
                std::cout << inner << " ";
            }
            
                while (inner < outer)
                {
                    inner++;
                        
                    while (inner == outer)
                    {
                        while (inner >= 1)
                        {
                            std::cout << inner- << " ";
                        
                        }
                        
                    }
                
                    if (inner == 0)
                    {
                        break;
                    }
                }
            
            std::cout << "\n";
        

            outer-;
        }

        return 0;

    }

  • 赵杰

    and how is my solution to the penult question?

    and is the use of the break for stoping the current inside function and jump

    out of the function and then the numerical number of the " inner" never change,

    is that right?( I means the inner in my function), thank you very much!

    #include"stdafx.h"
    #include<iostream>

    int main() {
        int outer = 5;
        while (outer >= 1) {
            int inner = 1;
            if (inner == outer)
            {
                std::cout << inner << " ";
            }
            
                while (inner < outer)
                {
                    inner++;

                        std::cout << inner- << " ";
                        
                    while (inner == outer)
                    {
                        while (inner >= 1)
                        {
                            std::cout << inner- << " ";
                        
                        }
                        
                    }
                
                    if (inner == 0)
                    {
                        break;
                    }
                }
            
            std::cout << "\n";
        

            outer-;
        }

        return 0;

    }

    • Alex

      When I ran this, it looped forever printing 2 2 2 2 2 … so clearly not a correct solution. Nesting so many while loops is hard to read. Generally you should try not to nest more than a couple of levels deep (if you need to nest more, use a function).

  • 赵杰

    hi, Alex, how is my solution to the last question?
    is it OK?
    int main() {
        int outer = 1;
        while (outer <= 5) {
            int inner = outer;
            int space = 5 - inner;
            while (space > 0) {
                std::cout << " "<<" ";
                space-;
            }
            while (inner >= 1) {
                std::cout << inner-<<" ";
            }
            std::cout << "\n";

        
            outer++;
        }
        return 0;

    }

  • ppippi

    Hi Alex, is there any reason why you should use

    instead of

    Does it matter which one is used? I know that ++myChar increments then evaluates the char and myChar++ does the opposite but does it matter in this instance? Does it ever? Here, I get the same output for both. Thanks!

    • Alex

      You should always use the prefix version of ++ if you can. It’s more efficient. The only time you should use the postfix version is when you actually need something to be incremented after its evaluated, which should be rare.

  • Mike

    // Why isn’t this code working please help Alex and others.
    [code]
    #include "stdafx.h"
    #include <iostream>
    using namespace std;

    int main()
    {
        int outer = 4;
        while (outer >= 0);
        {
            int inner(5);
            while (inner - outer > 0);

            cout << inner--;

            cout << endl;
            --outer;

        }
            return 0;
        
        
    }
    [code]

  • Ben

    Hi Alex, when you use inner++ in this context

    while (outer <= 5)
        {
            // loop between 1 and outer
            int inner = 1;
            while (inner <= outer)
                std::cout << inner++ << " ";

            // print a newline at the end of each row
            std::cout << "n";
            ++outer;
        }

    what makes each line print all the values less than outer, lets say on the third line (1 2 3) instead of just the incremented value of inner (3) ?

  • keikari

    Is it acceptable to declear

    inside loops, instead of declearing it outside of loop as

    ? Or is there somehting that can cause some problem when doing so?

    • Alex

      The general rule of declaring variables applies here: you should declare your variables in the smallest scope that they are needed. If you can declare a static variable inside a function (or inside a loop), that’s better than declaring a global variable in the global namespace.

  • M Hassan Tahir

    This code works only with brackets enclosing the while loop statements. If I remove the brackets, the loop keeps on executing without stopping with an unexpected result but i can’t understand the reason. Please guide.

    • M Hassan Tahir

      The brackets are really confusing to me. At one place you need to remove them and at the other you need to add them. Great tutorials by the way!

    • Alex

      If you don’t include brackets, the while loop only executes the statement immediately after the while loop. Your ++count line never executes in that case.

      Not including brackets for the loop body is the equivalent of writing:

  • Prajwal Kulkarni

    Hey Alex,
    A Small doubt,from a simple question which i was recently trying to solve.
    Q:Write a program which prints numbers from 1 to 100. If a number is a multiple of 3, print Fizz, if it is a multiple of 5 print Buzz, it it is a multiple of both 3 and 5, print FizzBuzz, else print the number.

    And my answer to this ques is as follows:

    And the output was pretty as much as expected,but a small glitch perhaps,if a number is  multiple of 5 or 3 or both,the word along with the count number is printed,say for example 12 is a multiple of 3,so the expected output is "Fizz" but instead "Fizz 12" is being printed,same with Buzz and FizzBuzz,how to solve it ?And What’s the reason behind even the count number occurring after the the word ?

    Eagerly waiting for your answer,
    Regards,
    Prajwal.

  • Son Ngo

    Hey Alex, i am having some trouble in my code:

    It works fine, but if i add a space to cout<<j: cout << j << " ";, it prints out a triangle. Did i do something wrong? Thank you.

    • Alex

      It prints out a triangle either way, just a different kind of triangle with and without the space. I’m not sure how to answer the question if “Did i do something wrong?” since it’s not clear what you were trying to do in the first place.

  • Rodrigo Silva

    At Nested Loops, There is a {} missing in the second while, I think so.

    Thanks for this page, It is really amazing, I have learned a lot thanks to it
    Thanks again!

    • Alex

      No, it’s correct as-is. While loops don’t require curly braces if the loop body is only a single statement.

      • Rodrigo Silva

        I see, is this the same with the for loop? if there is only one statement, no need {}?
        if you don’t type {} the loops just execute the first statement, the rest is out of the loop?

        Thanks for the answer, your work at this page is really good.

  • Alex

    This code is for #4 🙂

  • Jane Doe

    Solution to 3. My brain didn’t see the nice simple solution.

    • Jane Doe

      Is it bad to get a different answer? My answer wasn’t as neat.

      • Alex

        Different isn’t bad in and of itself. There are often many ways to solve the same problem at the same level of quality. What’s worse is if the alternative solution is a lower quality solution in terms of readability, performance, robustness, etc…

  • Jane Doe

    Ummmm maybe we shouldn’t name our loop variables kkk… You are kinda sending the wrong message here Alex.

  • abaidullah

    a C++ program that first reads lower and upper limits and reads 10 numbers from the user. The program
    should print numbers of time a number is in between the given limits
    I Need this program with whilw loop

  • Amber

    This may have been asked and answered but I have a question about the increments. In your final example in this section, you use a post-increment on "inner" and a pre-increment on "outer." Then in question #2, you use a post-increment on "chValue" (on my first attempt before looking at your solution, I used a pre-increment because I thought "chValue" was very similar to the "outer" variable in your example). How are you determining whether to do a pre- or post-increment? Back when you first talk about increments in Chapter 3, you mention that as a general rule it is better to favor pre over post. I am having a hard time figuring out which one I am supposed to use in certain situations, and you don’t really go into details about why you are choosing one over the other (unless I missed something).

    • Alex

      I always favor pre-increment unless there’s a specific reason to use post-increment. I used a post-increment in the inner loop because I want to print a value and THEN increment it.

      The chValue post-increment should have been a pre-increment -- just a mistake on my part. I’ve updated the example.

  • fernando

    Write a program that will take from user two signs on interval [‘a’, ‘z’] and print out pyramid made of
    letters. For example, if ‘c’ and ‘g’ are entered, pyramid should look like this:
    c
    cdc
    cdedc
    cdefedc
    cdefgfedc

  • Patrick

    Hi Alex,

    I try to create functions to solve your quizzes in this chapter. It is my understanding that each function should complete one task only.

    In commercial applications/code, is there a lot of code in the main() function or only one statement that points to other class file(s) with functions? What is best practice here?

    For example under exercise 4, I only have PrintExercise() in the main() function but I don’t know if this is advisable and the right thing to do. Could you please shed some light based on your professional experiences?

    • Alex

      It totally depends on the program and programmer. I’ve seen main() functions that are super long, and main functions that are super short.

      I personally tend to write main() functions that look like some variant of this:

      • Patrick

        Thank you for sharing your review and your setup makes perfect sense to me. I almost see the main() function as a table of content for the program. Meaning that function calls listed under the main functions are calls to distinct top hierarchy components of the program.

  • Hani-7amad

    hello guys
    I have a little problem
    and I don’t know from where to start :ermm:
    there is a program I couldn`t write
    and I`d like to ask you if you could help me , I`d appreciate so much

    here it is

    http://i.imgur.com/kctDHPO.png

    http://i.imgur.com/nbdgd5C.png

    I’m really struggling , Plz help me here
    thank you.

  • joy

    how to do this?? Problem

    1 + 1 = 2
    2 + 2 = 4
    3 + 3 = 6
    4 + 4 = 8
    5 + 5 = 10

    thanks for response. 🙂

  • joy

    how to do this?? Problem

    * * * * * * * * * *
    * * * * * * * * * *
    * * * * * * * * * *
    * * * * * * * * * *
    * * * * * * * * * *
    * * * * * * * * * *

  • Joshua Richards

    Hi Alex,
    I did question 4 a bit differently and was wondering what you thought about it?

    #include <iostream>

    int main()
    {
       int count = 1;
       while (count <= 5)
         {
            switch (count)
            {
               case 1:
               {
                  std::cout << "        1\n";
                  break;
               }
               case 2:
               {
                  std::cout << "      2 1\n";
                  break;
               }
               case 3:
               {
                  std::cout << "    3 2 1\n";
                  break;
               }
               case 4:
               {
                  std::cout << "  4 3 2 1\n";
                  break;
               }
               case 5:
               {
                  std::cout << "5 4 3 2 1\n";
                  break;
               }
            }
            ++count;
         }
         return 0;
    }

    • Alex

      It works, but it sort of misses the point of the lesson. What would you have done if I’d ask you to do this with 100 rows instead of 5? 🙂

  • Elpidius

    Hey Alex, I just noticed 2 typos.

    The first is at the top, right before the first example:
    "The following program prints all the numbers from 0 and 9", which should read "0 to 9".

    Also at the end, in the last example, inside the inner loop:

    Should read:

  • Sandro

    Hello. In the second quiz, I first tried this (wrongly):

    This returns something like "b = 97 …". Shouldn’t it print like "a = 98 …"?

    I understand that the precedence of the parenthesis is higher than the "++" operator.

    • Alex

      Regardless of how this statement is evaluated, it breaks one of the cardinal rules of programming in C++: Don’t use any variable that has a side effect applied more than once in a single expression. Doing so is just begging for trouble.

      It does appear chValue++ is being evaluated first. chValue starts at value 97. static_cast(chValue++) evaluates to int 97, and chValue is incremented. Then everything is printed left to right: chValue is ‘b’, and the static_cast already evaluated to 97, so you get b = 97.

  • Roberto

    Hi Alex!
    I’ve solved exercise 2 like this instead:

    let me know if it’s fine the same. thanks!

    • Alex

      Since you’re using chars, you really should use char literals (e.g. ‘a’) instead of integer literals (97).

      You could also static_cast count to a char in your output statement rather than assign count to a temporary char variable to do the conversion.

Leave a Comment

Put C++ code inside [code][/code] tags to use the syntax highlighter