5.7 — For statements

By far, the most utilized looping statement in C++ is the for statement. The for statement (also called a for loop) is ideal when we know exactly how many times we need to iterate, because it lets us easily define, initialize, and change the value of loop variables after each iteration.

The for statement looks pretty simple in abstract:

for (init-statement; condition-expression; end-expression)

The easiest way to understand a for loop is to convert it into an equivalent while loop:

{ // note the block here
    while (condition-expression)
} // variables defined inside the loop go out of scope here

The variables defined inside a for loop have a special kind of scope called loop scope. Variables with loop scope exist only within the loop, and are not accessible outside of it.

Evaluation of for statements

A for statement is evaluated in 3 parts:

1) The init-statement is evaluated. Typically, the init-statement consists of variable definitions and initialization. This statement is only evaluated once, when the loop is first executed.

2) The condition-expression is evaluated. If this evaluates to false, the loop terminates immediately. If this evaluates to true, the statement is executed.

3) After the statement is executed, the end-expression is evaluated. Typically, this expression is used to increment or decrement the variables declared in the init-statement. After the end-expression has been evaluated, the loop returns to step 2.

Let’s take a look at a sample for loop and discuss how it works:

First, we declare a loop variable named count, and assign it the value 0.

Second, count < 10 is evaluated, and since count is 0, 0 < 10 evaluates to true. Consequently, the statement executes, which prints 0.

Third, ++count is evaluated, which increments count to 1. Then the loop goes back to the second step.

Now, 1 < 10 is evaluated to true, so the loop iterates again. The statement prints 1, and count is incremented to 2.
2 < 10 evaluates to true, the statement prints 2, and count is incremented to 3. And so on.

Eventually, count is incremented to 10, 10 < 10 evaluates to false, and the loop exits.

Consequently, this program prints the result:

0 1 2 3 4 5 6 7 8 9

For loops can be hard for new programmers to read -- however, experienced programmers love them because they are a very compact way to do loops of this nature. For the sake of example, let's uncompact the above for loop by converting it into an equivalent while loop:

That doesn't look so bad, does it? Note that the outer braces are necessary here, because count goes out of scope when the loop ends.

More for loop examples

Here's an example of a for loop used to calculate an exponentiation of integers:

This function returns the value base^exponent (base to the exponent power).

This is a straightforward incrementing for loop, with count looping from 0 up to (but excluding) exponent.

If exponent is 0, the for loop will execute 0 times, and the function will return 1.
If exponent is 1, the for loop will execute 1 time, and the function will return 1 * base.
If exponent is 2, the for loop will execute 2 times, and the function will return 1 * base * base.

Although most for loops increment the loop variable by 1, we can decrement it as well:

This prints the result:

9 8 7 6 5 4 3 2 1 0

Alternately, we can change the value of our loop variable by more than 1 with each iteration:

This prints the result:

9 7 5 3 1

Off-by-one errors

One of the biggest problems that new programmers have with for loops (and other kinds of loops) is off-by-one errors. Off-by-one errors occur when the loop iterates one too many or one too few times. This generally happens because the wrong relational operator is used in the conditional-expression (eg. > instead of >=). These errors can be hard to track down because the compiler will not complain about them -- the program will run fine, but it will produce the wrong result.

When writing for loops, remember that the loop will execute as long as the conditional-expression is true. Generally it is a good idea to test your loops using known values to make sure that they work as expected. A good way to do this is to test your loop with known inputs that cause it to iterate 0, 1, and 2 times. If it works for those, it will likely work for any number of iterations.

Rule: Test your loops with known inputs that cause it to iterate 0, 1, and 2 times.

Omitted expressions

It is possible to write for loops that omit any or all of the expressions. For example, in the following example, we'll omit the init-statement and end-expression:

This for loop produces the result:

0 1 2 3 4 5 6 7 8 9

Rather than having the for loop do the initialization and incrementing, we've done it manually. We have done so purely for academic purposes in this example, but there are cases where not declaring a loop variable (because you already have one) or not incrementing it (because you're incrementing it some other way) are desired.

Although you do not see it very often, it is worth noting that the following example produces an infinite loop:

for (;;)

The above example is equivalent to:

while (true)

This might be a little unexpected, as you'd probably expect an omitted condition-expression to be treated as "false". However, the C++ standard explicitly (and inconsistently) defines that an omitted condition-expression in a for loop should be treated as "true".

We recommend avoiding this form of the for loop altogether and using while(true) instead.

Multiple declarations

Although for loops typically iterate over only one variable, sometimes for loops need to work with multiple variables. When this happens, the programmer can make use of the comma operator in order to assign (in the init-statement) or change (in the end-statement) the value of multiple variables:

This loop assigns values to two previously declared variables: iii to 0, and jjj to 9. It iterates iii over the range 0 to 9, and each iteration iii is incremented and jjj is decremented.

This program produces the result:

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

This is the only place in C++ where the comma operator typically gets used.

Note: More typically, we'd write the above loop as:

In this case, the comma in the init-statement is part of the variable definition syntax, not a use of the comma operator. But the effect is identical.

For loops in old code

In older versions of C++, variables defined as part of the init-statement did not get destroyed at the end of the loop. This meant that you could have something like this:

This use has been disallowed, but you may still see it in older code.

Nested for loops

Like other types of loops, for loops can be nested inside other loops. In the following example, we're nesting a for loop inside another for loop:

For each iteration of the outer loop, the inner loop runs in its entirety. Consequently, the output is:


Here's some more detail on what's happening here. The outer loop runs first, and char c is initialized to 'a'. Then c <= 'e' is evaluated, which is true, so the loop body executes. Since c is set to 'a', this first prints 'a'. Next the inner loop executes entirely (which prints '0', '1', and '2'). Then a newline is printed. Now the outer loop body is finished, so the outer loop returns to the top, c is incremented to 'b', and the loop condition is re-evaluated. Since the loop condition is still true the next iteration of the outer loop begins. This prints ("b012\n"). And so on.


For statements are the most commonly used loop in the C++ language. Even though its syntax is typically a bit confusing to new programmers, you will see for loops so often that you will understand them in no time at all!


1) Write a for loop that prints every even number from 0 to 20.

2) Write a function named sumTo() that takes an integer parameter named value, and returns the sum of all the numbers from 1 to value.

For example, sumTo(5) should return 15, which is 1 + 2 + 3 + 4 + 5.

Hint: Use a non-loop variable to accumulate the sum as you iterate from 1 to the input value, much like the pow() example above uses the total variable to accumulate the return value each iteration.

3) What's wrong with the following for loop?

Quiz solutions

1) Show Solution

2) Show Solution

3) Show Solution

5.8 -- Break and continue
5.6 -- Do while statements

208 comments to 5.7 — For statements

  • BP

    Could somebody look at my code and please point out how to make it better?

    So this is for making a piramide of numbers with any given integer between 0 and 10.

    I tried making code for a diamond as well but only came up with this:

    This is where I really need help, because I'm pretty sure there would be a way to make this code more compact, but I can't see it. Please help!

    • BP

      I strangely can't edit my comment,
      But I know in the second piece of code my variable names are the same.
      Please ignore that, as I just copied the first and tweaked it here and there.

    • - Use single quotation marks for characters.
      - You're using the same name style for variables and functions, this can lead to confusion.

      In your diamond code, line 9-22 and 29-42 are identical. Don't repeat code. Whenever you notice that you repeat code, you should use a loop, or add a function. Try exporting the loop's body to a function such that `localMain` is only

      • BP

        I had it working, but suddenly the char(literal?) ' ' in the short if statement is changed to an int.
        And the ASCII number is printed instead. The strange thing is that the precise same code didn't do that just a few minutes ago... I don't know what I did wrong.

        • My bad, both types in the conditional operator should be the same. Since they're not (`int` vs `char`), the ' ' will be converted to an `int`.
          The easiest fix is reverting to your original `if`-statement.

  • This one print nicely!

    • - Use single quotation marks for characters.
      - Inconsistent formatting. Use your editor's auto-formatting feature.
      - Use ++prefix unless you need postfix++.
      - Line 15+: Should be a for-loop, because you know how long the loop will run before you start it.

      Apart from that your code look good :)

  • guys help me how to restart my program automatically ?

  • Dimbo1911

    Is this kind of usage of passed value to the function ok, or is it frowned upon (in for loop inside the sumTo function)? Thank you for the fast replies.

  • Alireza


    What's wrong with this kind of for loop ? (I always use it)

  • Lorenz

    anything wrong with this way of implementing quiz 2?

    • * Line 6: Initialize your variables with brace initializers. You used copy initialization.
      * Line 15: Initialize your variables with brace initializers.
      * @main: Missing return-statement.
      * Line 6: The check should be (iii > 0), since adding 0 has no effect.

      • Lorenz

        Wow, that was quick!

        - Line 15: is it necessary to initialize the variable? it will be changed the line after
        - @main: I always forget, why visual studio does not complain about this?


        • > is it necessary to initialize the variable?
          No. @std::cin::operator>> overrides values even if an extraction error occurs. Initializing all variables makes debugging easier and prevents forgetting an initialization where you would've needed it.

          > why visual studio does not complain about this?
          @main's return-statement is optional. If it is omitted, 0 is returned. For consistency with all other functions, a return-statement should be given explicitly.

  • Paulo Filipe

    @alex @nascardriver Have you guys ever considered doing a learcpp discord? It would be really good for us readers to exchange impressions / make more real time q&a

  • paparob76


    For Question 2 in the quiz above, how would you call the function then print its return value?
    I initialized an int x, passed it to the function but get no return value. How would you do that to get the value passed back to main() to print or use for another task?

  • rovin mariano


    for the nested for loops, why is the inner loop executes entirely on that part? just really confused about this one. thank you!

    • Alex

      In a single loop, the loop body runs entirely for each iteration.

      If the loop body itself contains a loop, that inner loop runs as per normal.

      Therefore, in a nested loop, for each iteration of the outer loop, the loop body runs entirely, which contains an inner loop that runs entirely before the next iteration of the outer loop.

      • rovin mariano

        So it will be like this:
        Outer Loop: This loop runs normal for each iteration
        Inner Loop: For each iteration of outer , the inner runs entirely, so it means it will not count the iteration and will print out the entire loop output at once.

        Thank you!

        • Alex

          Yes. The outer loop only iterates when the outer loop body is complete. The outer loop body won't complete until the inner loop runs entirely.

          Therefore, the inner loop will run entirely each time the outer loop iterates.

  • Martian

    For practice I wrote this code to make a checkered pattern:

    • Hi Martian!

      0 % 2 is 0. (number == 0) will never evaluate to true.
      You're calling @isEven in every cycle of the inner for-loop. However, the evenness of @rowCount will only ever change with a cycle of the outer for-loop. It's more efficient to add a bool whose values you swap with every cycle of the outer loop.

      Other than that your code looks fine. Writing practice code will help you understanding concepts of the language. Keep it up :)

      • Martian

        Thanks a lot, nascardriver! I improved it a little!
        I found that I don't even need a function, I can just keep switching boolean variables.
        Any other suggestion is welcome!

        • Martian

          I don't want to spam (I already edited the last post until the last minute) but I made some other changes.

          Changed the names of the boolean variables to be more descriptive of what they actually are:

          Went back to the conditional operator for printing:

          • * Remove line 9
            * Change Line 13-16 to

            * Your new conditional operator: Don't compare booleans to false/true. They are booleans already.
            std::cout << (whiteCell ? ' ' : '#');

            • Martian

              Thanks again! A lot better and just 20 lines!
              Question: how do you decide if it's better to initialize a variable in each loop or change an out of loop variable if both options could work?

              • If I don't need the variable's value of the last cycle, I declare the variable inside the loop to limit the variable's scope. Every compiler should be able to handle the situation during optimization, such that it doesn't matter if the variable is declared outside or inside of the loop.
                With custom types, it can be better to declare the variable outside of the loop. That way, if you only need some parts of the variable to reset, you don't need to reset everything.

    • Paulo Filipe

      Hello, you inspired me to do the same, and here is my version of it.

      Note that my program can print a checkerboard of the size inputted by the user.

      @nascardriver, I know my lines are too long. =P My android c++ ide doesn't count the number of characters in a line, so I ignore this when I code on my phone.

      • Hi Paulo!

        Use single quotation marks for characters. ('\n' instead of "\n").
        Limit your source code to ASCII for increased compatibility. Replace the squares with "\u2B1C" and "\u2B1B" respectively (Note: These aren't 8bit characters, so use quotation marks).
        Rest looks good!

  • Ajalle Perfej

    Hi, Steve!

    What do you think of this solution for question 2?

    The continue can be replaced with other code that's more useful.

    • Hi Ajalle!

      Declare one variable per line, it makes your code easier to read.
      Only use auto for templated types or in for-each loops, it makes your code easier to understand.
      Don't merge the loop body with the increment expression, it makes your code harder to read.

      You can start your loop at 1, change your condition to counter < value and initialize @sum to @value.

      You can remove the continue and just have an empty loop body (But keep the semicolon). I forgot the name for this.

      Although I'm not a fan of your code, it shows that you have a good understanding of for-loops.

  • erwgt 4vwgh etbe gv trw4tvwgf

    My solution.

    • Hi!

      Names should be descriptive, "a" could be names "sum" or similar.
      Line 7: Use uniform initialization.
      If you don't print a line break at the end of you program, whatever comes next in the console will be on the same line, which look ugly.

  • Clapfish

    Hi Alex!

    Small typo here at the bottom of the 'Omitted expressions' section:

    "However, the C++ standard explicitly (and inconsistently) defines that and omitted condition-expression in a for loop should be treated as "true"."

    I believe that should read "...defines that *an* omitted..."

  • Alex

    I've being strugling with the exercise 2 and i don't know why but it keeps printing one as result.

    • Hi Alex!

      * You're not using the return value of @sumTo.
      * @main's parameter list is wrong
      * @main is missing a return statement
      * Initialize your variables with uniform intialization
      * Don't use <Windows.h> unless you have to
      * Don't use @Sleep
      * Don't use "using namespace"

      Lesson 1.1, 1.4, 2.1

  • vitrag shah

    Hi Alex,

    I am making the code that does multiplication of the matrix

    here after printing the second matrix, the error message is pop-up

  • Kio

    Also @Alex in the beginning you have written this:
    "3) After the statement is executed, the end-expression is evaluated. Typically, this expression is used to increment or decrement the variables declared in the init-statement. After the end-expression has been evaluated, the loop returns to step 2."

    And before "Conclusion" part you have
    " Then a newline is printed. Now the loop body is finished, so the outer loop returns to the top and the loop condition is re-evaluated. Since the loop condition is still true, variable c (with value 'a') is incremented (to value 'b'), and the next iteration of the outer loop begins. This prints ("b012\n"). And so on.".

    "Since the loop condition is still true, variable c (with value 'a') is incremented (to value 'b'), and the next iteration of the outer loop begins." -> we first increment the value. Then we check if the loop condition is true or false. Should we change this, to fit the text from the beginning?


  • Aakash

    Conclusion, which is sub heading, should come in new line, not in previous one

  • Hi,

    for the second one I initialised int sum as a global variable in order to test the for loop in the following solution:

    • Hi Nigel!

      Come on Nigel, uniform initialization isn't that hard, you can do it!

      • sorry, Ok, I know it wasn't the best planned solution and maybe global variables are evil - at least I didn't set them up in a header file.

        sorry for the terrible jokes also..

  • jörg

    is it bad to use the direct- or uniform initialization to initialize the loop variable?

  • Nudzekalo

    Hi. I think the explanation of the example for nested for loops is in contradiction with the part Evaluation of for statements given above. You say that after the char c is set to 'a' the loop body is executed and after that the condition is evaluated and since it is true c is incremented. Isn't condition evaluated before executing body?
    Thank you for your time. :)

  • Aditi

    Hi ! I had a question about the program under Multiple Declarations. If iii=0 , and jjj=9 , and we used the pre increment/decrement operator, why does the program print the original values of iii and jjj? I think that should’ve happened when we used the post increment/decrement operator right ? In this case the iii that we send to cout the first time is iii+1 isn’t it ?

  • Dayyan218

    Hi Alex! You have used cout many times in this section over std::cout

  • Andrew George Mackay

    why do we always use < or > for the test in for loops, why do we never use ==
    for instance for(int i = 0; i ++ 20; i++)?

    • nascardriver

      Hi Andrew!

      You can usually replace the > condition with a != condition.
      The > condition has the advantage that if you increased the iterating variable beyond it's limit the loop will still stop.

      • Andy Mackay

        Thanks for the reply, I'm still not sure why the loop won't work with == thought, I always thought that the for loop continues until the condition you give in the middle becomes true, so you'd think it would stop when the control variable is equal to say 5 in our examples, but it doesn't. I get the feeling I am missing some subtle point somewhere.

        • nascardriver

          The loop runs as long as the condition is true. It stops when the condition is false.

  • Ziyo Jabborov

    using namespace std;

    int main(){
        int row=9;
        int col=9;

        for(int i=1;i<=row;++i){
            for(int j=1;j<=col;++j){
        return 0;
    Hi I need a help !!
    How can i make it like this :
                     * * *
                     * * *
                     * * *
            * * * * * * * * *
            * * * * * * * * *
            * * * * * * * * *
                     * * *
                     * * *
                     * * *

    • J Gahr

      Here's a rough solution that will print the cross. Not sure if it goes about it the way that you wanted though.

    • Minh Quan

      I have this solution as the below code.

      #include <iostream>

      int main()
          for (int i = 1; i <= 9; ++i)
              for (int j = 1; j <= 9; ++j)
                  if (i<=3 || i>=7)
                      if (j>=4 && j<=6)
                          std::cout << "*" << " ";
                          std::cout << "  ";
                      std::cout << "*" << " ";
              std::cout << std::endl;      
          return 0;

    • Martian

      Another solution to your cross:

Leave a Comment

Put all code inside code tags: [code]your code here[/code]