Search

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)
   statement;

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

{ // note the block here
    init-statement;
    while (condition-expression)
    {
        statement;
        end-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:

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 (;;)
    statement;

The above example is equivalent to:

while (true)
    statement;

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:

a012
b012
c012
d012
e012

Here's some more detail on what's happening here. The outer loop runs first, and char c is set to 'a'. Then the loop body executes, with c set to 'a'. This prints 'a', executes the inner loop entirely (which prints '0', '1', and '2'). 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 true, c is incremented (to 'b'), and the next iteration of the outer loop begins. This prints ("b012\n"). And so on.

Conclusion

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!

Quiz

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
Index
5.6 -- Do while statements

99 comments to 5.7 — For statements

  • Shane

    For number 3 you also didn’t use std:: before cout and didn’t use the namespace. Do I get bonus points? 😀

  • Shane

    Alex I finally accomplished something without messing it up or overcomplicating it. I’m so happy right now.

  • SO I MADE THIS PROGRAM WHICH USES "WHILE" LOOPS TO DEMONSTRATE THE WORKING OF "FOR" LOOPS.
    ITS OBVIOUSLY NOT PERFECT. SO I REQUEST YOU TO TEST IT AND TELL ME IF IT WORKS IN EVERY WAY A "FOR" LOOP SHOULD WORK.

    ALSO, PLEASE TELL ME HOW IT COULD’VE BEEN BETTER AND MORE READABLE(I TRIED AS MUCH AS I COULD TO MAKE IT READABLE). IT WOULD BE VERY KIND OF YOU.

    #include<iostream>

    using namespace std;

    int ForLoop(double  i, double  j,double  k,char ch)
    {
        switch(ch)
        {
    /*case 1. for
    increasing order*/       case ‘+’:
                               {
                                   while(i<=j)
                                   {
                                     cout<<i<<" ";
                                      i=i+k;
                                   }
                                    break;
                               }
    /*case 2. for
    decreasing order */      case ‘-‘:
                                {
                                   while(i>=j)
                                   {
                                      cout<<i<<" ";
                                      i-=k;
                                   }
                                      break;
                                }
    /*case 3. increment
    by multiplication
    */                        case ‘*’:
                                 {
                                     while(i<=j)
                                     {
                                      if(k==1)
                                        {
                                           cout<<"your k is equal to one\ntherefore it will not update your \"initial value\"";
                                           exit(0);
                                        }
                                          else
                                         {  cout<<i<<" ";
                                              i*=k;
                                         }
                                     }
                                            break;
                                 }
    /*case 4. decrement
      by division*/             case ‘/’:
                                  {
                                    while(i>=j)
                                     {
                                      if(k==0)
                                       {
                                        cout<<"your \"k\" is equal to zero\n\nso \"i\" cannot be updated";//because a number cannot be divide by zero
                                         exit(0);
                                       }
                                       else if(k==1)
                                        {
                                   cout<<"WARNING: k equals 1\nso i will not be updated"<<endl;//because number divided by one will result in same number
                                        exit(0);
                                        }
                                         else
                                          {
                                            cout<<i<<" ";
                                            i/=k;
                                          }
                                     }
                                       break;
                                    }
    /*case 5. default*/         default :
                                    cout<<"\nuh oh! the operator is invalid"<<endl;
        }
    }
    int main()
    {
        cout<<"enter the initial value"<<endl;
        double  initial_value;
        cin>>initial_value;

        cout<<"till what value the loop should execute?"<<endl;
        double  val;
        cin>>val;

        cout<<"enter the value by which the \"initial value\" should  be updated" <<endl;
        double  update;
        cin>>update;

        cout<<"enter the relation between \"i and k\""<<endl;
        char relation;
        cin>>relation;

         ForLoop(initial_value,val,update,relation);
    }
    REGARDS, ADITYA RAWAT

  • JimD

    Alex, re quiz question 2, I’m not seeing the need for the extra count variable. Before looking at the solution I wrote the following and it seems simpler (unless I’m missing something…).

  • JimD

    Hi Alex. A strange thing is happening while I’m trying out for loop examples from this chapter.

    My IDE is highlighting the word ‘count’ in green as if it’s a keyword (google says it isn’t a c++ keyword). It doesn’t seem to be happening in your code, or anyone else’s in the comments. Do you know what the reason for this is?

    The programmes are working fine, this is just bugging me because I don’t know what’s going on.

    I’m using Code::Blocks 13.12 in linux Mint.

    • Alex

      I don’t have a clue on this one. Maybe that word is a keyword for some other language Code::Blocks supports? The internets says Code::Blocks supports Fortran, and Count is a function in Fortran…

      • JimD

        Maybe that’s it, though you would think Code::Blocks would take account of the selected compiler before highlighting words. As I said, it isn’t causing any functional problems, so just a niggle. 🙂

    • in code::blocks the variables that are mostly used by users  act as a keyword( but they are not keywords, they are just there to suggest you that you might want to use this variables, example count).

      they are just normal variables which may get  highlighted, although you still have to declare and initialize them( as normal variables).

  • Lucas F.

    Altough the point of quiz 2 is to illustrate a use for a for loop (pun not intended), as a side note I believe if I ever needed to calculate that sum I would use this, which is more direct and WAY faster for very large numbers (the largest input it handles without overflow is 6 074 000 999).

    At least a couple of people in the comments pointed this formula out, but they implemented it with double division with its accuracy problems, analogously to this:

    That is not needed because if x is a natural number then necessarily either x or x+1 is even!
    Sorry for being fussy 🙂

  • Nicolas

    Hello Alex,
    I thought I’d experiment around a little bit with structs and enums and spent a chunk of time writing this code:

    The code compiles fine but I get a runtime  error: "Debug error! …. " "abort() has been called". Any idea why and how to fix it?

  • Nicolas

    Hi Alex,
    Im a little confused about why in the nested loop example the nested loop executes 3 times before the newline but the actual loop only executes once before the newline. why doesnt the program print the following?

    a0
    b1
    c2
    d0
    e1

    • Alex

      The outer loop starts executing first, and c = ‘a’. Then the code in the body of the loop runs. This first prints ‘a’. Then the nested loop runs in its entirety. This prints “012”. Only when the outer loop block finishes does the outer loop begin its second iteration (c = ‘b’). The second iteration prints “b012”. Then the third iteration of the outer loop runs. Etc…

      • Nicolas

        I think you mean "only when the inner loop block finishes", makes sense. Thanks a lot!

        • Alex

          Well, both actually. The inner loop block finishes all of its iterations, then the outer loop block finishes its single iteration, then the outer loop re-evaluates the loop condition.

  • sorry i just wanted to share this:
    the formula for the sum of the natural numbers
    is 0.5*n*(n+1)

  • Russell

    I wrote the following for question 2, but return acc; doesn’t actually display anything - I have to cout acc. Am I doing something wrong?

    int sumTo(int value)
    {
            int acc = 0;
            for(int count = 1; count <= value; ++count)
            {
                    acc += count;
            }
            return acc;
    }

    int main()
    {
            std::cout << "Enter an integer: ";
            int value;
            std::cin >> value;

            sumTo(value);

            return 0;
    }

    • Alex

      You’re so close. sumTo() is great, and it returns the value of variable acc back to main(). However, main is not doing anything with this value, so it’s discarded.

      Change this:

      to:

      or

  • Grey

    thank you very much Mr Alex, After learning a couple of your tutorials up to here, i came out with this program.
    but please:
    1. i want a way that a user can input either Y or y, N or n to proceed.
    2. i want a way that, when the user select N/n, the program should ask him/her to re-select it or select 5 to exit it.

    please how do i do it. thank you once again and May GOD Blessed you.

    /*
    Calculating for temperature: conversations units between
    Degrees Celsius and Degrees Fahrenheit.
    */
    #include <iostream>

    using namespace std;

    int main()
    {
        int number;
        
        string ans;
        
        float c, f;
        
        cout << "Know your temperature scale!"
            << endl << endl;

        cout << "This program will help you to enter any temperature value to change from:"
            << endl << endl;

        cout << "1. Degrees Celsius to Degrees Fahrenheit."
            << endl << endl;

        cout << "2. Degrees Fahrenheit to Degrees Celsius."
            << endl << endl;

        cout << "Please enter [Y] to continue or [N] to exit this program:"
            << endl << endl;

        cin >> ans;

        cout << endl;
        if (ans == "y")
        {
            cout << "You want to know more!"
                << endl << endl;
                
            cout << "To change Degrees Celsius to Degrees Fahrenheit"
                << endl << endl;
                
            cout << "Please enter [1]"
                << endl << endl;
                
            cout << "To change Degrees Fahrenheit to Degrees Celsius"
                << endl << endl;
                
            cout << "Please enter [2]"
                << endl << endl;
                
            cin >> number;
            
            cout << endl;
            
            if (number == 1)
            {
                cout << "You are changing from Degrees Celsius to Degrees Fahrenheit!"
                    << endl << endl;
                    
                cout << "Please enter value in Degrees Celsius"
                    << endl << endl;
                    
                cin >> c;
                cout << endl;
                
                f = (1.8 * c) + 32;
                cout << "The current temperature " << c << " Degrees Celsius is equal to " << f << " Degrees Fahreheit"
                    << endl << endl;
                    
                cout << "THANK YOU!"
                    << endl << endl;
            }
            else if (number == 2)
            {
                cout << "You are changing from Degrees Fahreheit to Degrees Celsius!"
                    << endl << endl;
                    
                cout << "Please enter your value in Degrees Fahrenheit"
                    << endl << endl;
                    
                cin >> f;
                cout << endl;
                c = (f - 32) / 1.8;
                
                cout << "The current temperature is " << f << " Degrees Fahrenheit is equal to " << c << " Degrees Celsius"
                    << endl << endl;
                    
                cout << "THANK YOU!"
                    << endl << endl;
            }
        }
        else
            if (ans == "N", "n")
            {
                cout << "don’t you want to know your temperature?"
                    << endl << endl;
                    
                cout << "THANK YOU!"
                    << endl << endl;
            }

        return 0;
    }

  • Nguyen

    Hi Alex,

    In the last example (Nested for loops), I don’t understand how for statement is evaluated (line 5).

    First, we declare a loop variable named C, and assign it the value ‘a’.

    Second, ‘a’ <= ‘e’ is evaluated.  How could it be true since ‘a’ & ‘e’ are not integers?

    Third, ++C is evaluated.  This can be understood as C = ‘a’ + 1.  I don’t understand how C = ‘a’ + 1 equals to ‘b’;

    Thanks,  Have a great day.

    • Alex

      ‘a’ and ‘e’ are chars, and chars are a type of integer that are interpreted based on their ASCII codes. ‘a’ is integer 97, and ‘e’ is integer 101.

      ++c means “c = c + 1”. If c is 97 (‘a’), then c + 1 is 98 (‘b’).

      Make sense?

  • Avijit Pandey

    I did this one like this:

    I just wanted to know if its okay to do it like that or is it less efficient for further uses. i am asking this because you did it differetly.

  • ravi

    u haven’t explained nested for loops..like the one used to print star patterns

    • Alex

      Nested for loops work just like other kinds of nested loops, which I cover in the lesson on “while statements”. I’ve added an example here too, just to show how it’s done with for loops.

  • Jonas

    I know this chapter covers for loops, but after I have wrote the solution with a loop I remembered Gauss. ^^

  • Ahmed Sohail

    1234567654321
    123456  54321
    12345    4321
    1234      321
    123        21
    12          1
    how to form such pattern

  • paltrow

    Duly noted! thank you very much : )

  • paltrow

    Thanks for the answer Alex.
    That means that I can’t use assignments (single equals) in the condition-expression of a for loop. As a learning programming I was testing the for loop and I was confused because the compiler didn’t warn me. The code just runs as it was ok.
    Thanks again for your very useful answer.

    • Alex

      You can use assignments in the condition-expression (as evidenced by the fact that the compiler lets you), but you generally won’t need to. Do your assignments in the initialization or post-loop portions.

  • paltrow

    Hi Alex, thanks for your great site, I have a question about the following for loop.
    I can’t understand why when the condition-expression is equal to 0 it doesn’t print anything?

    It works fine for i=4 to i=1, but for i=0 it prints anything…

    Thanks!

  • Guido Bai G

    Dear Alex.

    Great tutorials.

    Is there any reason not to use unified declaration inside a for loop?:
    for(int i{0}, j{10}; i < 11; ++i, -j).  It works but I see you are not using it.
    Thanks and best regads.

    • Alex

      You can definitely use uniform initialization here. There’s no reason not to, though it doesn’t matter much with integer loop variables.

      I don’t use it partly out of habit and partly because I find it a little harder to read when nested inside a for loop.

  • Simrit Singh

    Hi alex,
    c++ program to make sure that computer always wins the 21 matchsticks game,my code fails in certin cases where i win,please help me modify it ?

    #include<iostream>
    using namespace std;
    int main()
    {
    int num1,n=0;
    int i=21;
    for(i;i>=1; ){
    cout<<"Enter the number of matchsticks:"<<endl;
    cin>>n;
    i=i-n;
    if(n>4){
    cout<<"Invalid input"<<endl;
    continue;
    }
    num1=num1+1;
    if(num1>4){
    num1=num1-4;
    cout<<num1<<endl;
    i=i-num1;
    }
    if(i==4 || i==3 || i==2)
    num1=i-1;
    if(num1<=4){
    cout<<num1<<endl;
    i=i-num1;
    }
    if(i==1){
    cout<<"You Lost the Game"<<endl;
    break;
    }
    }
    return 0;
    }

Leave a Comment

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