By Stephen R. Davis

There is a seemingly useless operator in C++ known as the comma operator. It appears as follows: expression1, expression2;. This says execute expression1 and then execute expression2. The resulting value and type of the overall expression is the same as that of expression2.

Thus, you could say something like the following:

int i;
int j;
i = 1, j = 2;

Why would you ever want to do such a thing? Answer: You wouldn’t except when writing for loops.

The following CommaOperator program demonstrates the comma operator in combat. This program calculates the products of pairs of numbers. If the operator enters N, the program outputs 1 * N, 2 * N-1, 3 * N-2, and so on, all the way up to N * 1. (This program doesn’t do anything particularly useful.)

//
//  CommaOperator - demonstrate how the comma operator
//                  is used within a for loop.
//
#include <cstdio>
#include <cstdlib>
#include <iostream>
using namespace std;
int main(int nNumberofArgs, char* pszArgs[])
{
    // enter a target number
    int nTarget;
    cout << "Enter maximum value: ";
    cin  >> nTarget;
    for(int nLower = 1, nUpper = nTarget;
              nLower <= nTarget; nLower++, nUpper--)
    {
        cout << nLower << " * "
             << nUpper << " equals "
             << nLower * nUpper << endl;
    }
    // wait until user is ready before terminating program
    // to allow the user to see the program results
    cout << "Press Enter to continue..." << endl;
    cin.ignore(10, 'n');
    cin.get();
    return 0;
}

The program first prompts the operator for a target value, which is read into nTarget. It then moves to the for loop. However, this time not only do you want to increment a variable from 1 to nTarget, you also want to decrement a second variable from nTarget down to 1.

Here the setup clause of the for loop declares a variable nLower that it initializes to 1 and a second variable nTarget that gets initialized to nTarget. The body of the loop displays nLower, nUpper, and the product nLower * nTarget. The increment section increments nLower and decrements nUpper.

The output from the program appears as follows:

Enter maximum value: 15
1 * 15 equals 15
2 * 14 equals 28
3 * 13 equals 39
4 * 12 equals 48
5 * 11 equals 55
6 * 10 equals 60
7 * 9 equals 63
8 * 8 equals 64
9 * 7 equals 63
10 * 6 equals 60
11 * 5 equals 55
12 * 4 equals 48
13 * 3 equals 39
14 * 2 equals 28
15 * 1 equals 15
Press Enter to continue . . .

In this example run, 15 is the target value. You can see how nLower increments in a straight line from 1 to 15, while nUpper makes its way from 15 down to 1.

Actually, the output from this program is mildly interesting: No matter what you enter, the value of the product increases rapidly at first as nLower increments from 1. Fairly quickly, however, the curve flattens out and asymptotically approaches the maximum value in the middle of the range before heading back down. The maximum value for the product always occurs when nLower and nUpper are equal.

Could you have made the earlier for loop work without using the comma operator? Absolutely. You could have taken either variable, nLower or nUpper, out of the for loop and handled them as separate variables. Consider the following code snippet:

nUpper = nTarget;
for(int nLower = 1; nLower <= nTarget; nLower++)
{
    cout << nLower << " * "
         << nUpper << " equals "
         << nLower * nUpper << endl;
    nUpper--;
}

This version would have worked just as well.

The for loop can’t do anything that a while loop cannot do. In fact, any for loop can be converted into an equivalent while loop. However, because of its compactness, you will see the for loop a lot more often.