More Syntax Tricks—The Comma Operator

As you have seen, a block enables you to sneak two or more statements into a place where C++ syntax allows just one statement. The comma operator does the same for expressions, enabling you to sneak two expressions into a place where C++ syntax allows only one expression. For example, suppose you have a loop in which one variable increases by one each cycle and a second variable decreases by one each cycle. Doing both in the update part of a for loop control section would be convenient, but the loop syntax allows just one expression there. The solution is to use the comma operator to combine the two expressions into one:

++j, --i   // two expressions count as one for syntax purposes

The comma is not always a comma operator. For example, the comma in this declaration serves to separate adjacent names in a list of variables:

int i, j;  // comma is a separator here, not an operator

Listing 5.9 uses the comma operator twice in a program that reverses the contents of a string class object. (You could also write the program by using an array of char, but the length of the word would be limited by your choice of array size.) Note that Listing 5.6 displays the contents of an array in reverse order, but Listing 5.9 actually moves characters around in the array. The program in Listing 5.9 also uses a block to group several statements into one.

Listing 5.9. forstr2.cpp


// forstr2.cpp -- reversing an array
#include <iostream>
#include <string>
int main()
{
    using namespace std;
    cout << "Enter a word: ";
    string word;
    cin >> word;

    // physically modify string object
    char temp;
    int i, j;
    for (j = 0, i = word.size() - 1; j < i; --i, ++j)
    {                       // start block
        temp = word[i];
        word[i] = word[j];
        word[j] = temp;
    }                       // end block
    cout << word << " Done ";
    return 0;
}


Here is a sample run of the program in Listing 5.9:

Enter a word: stressed
desserts
Done

By the way, the string class offers more concise ways to reverse a string, but we’ll leave those for Chapter 16, “The string Class and the Standard Template Library.”

Program Notes

Look at the for control section of the program in Listing 5.9. First, it uses the comma operator to squeeze two initializations into one expression for the first part of the control section. Then it uses the comma operator again to combine two updates into a single expression for the last part of the control section.

Next, look at the body. The program uses braces to combine several statements into a single unit. In the body, the program reverses the word by switching the first element of the array with the last element. Then it increments j and decrements i so that they now refer to the next-to-the-first element and the next-to-the-last element. After this is done, the program swaps those elements. Note that the test condition j<i makes the loop stop when it reaches the center of the array. If it were to continue past that point, it would begin swapping the switched elements back to their original positions (see Figure 5.2).

Figure 5.2. Reversing a string.

Image

Another thing to note is the location for declaring the variables temp, i, and j. The code declares i and j before the loop because you can’t combine two declarations with a comma operator. That’s because declarations already use the comma for another purpose—separating items in a list. You can use a single declaration-statement expression to create and initialize two variables, but it’s a bit confusing visually:

int j = 0, i = word.size() - 1;

In this case the comma is just a list separator, not the comma operator, so the expression declares and initializes both j and i. However, it looks as if it declares only j.

Incidentally, you can declare temp inside the for loop:

int temp = word[i];

This may result in temp being allocated and deallocated in each loop cycle. This might be a bit slower than declaring temp once before the loop. On the other hand, after the loop is finished, temp is discarded if it’s declared inside the loop.

Comma Operator Tidbits

By far the most common use for the comma operator is to fit two or more expressions into a single for loop expression. But C++ does provide the operator with two additional properties. First, it guarantees that the first expression is evaluated before the second expression. (In other words, the comma operator is a sequence point.) Expressions such as the following are safe:

i = 20, j = 2 * i      // i set to 20, then j set to 40

Second, C++ states that the value of a comma expression is the value of the second part of the expression. The value of the preceding expression, for example, is 40 because that is the value of j = 2 * i.

The comma operator has the lowest precedence of any operator. For example, this statement:

cata = 17,240;

gets read as this:

(cats = 17), 240;

That is, cats is set to 17, and 240 does nothing. But because parentheses have high precedence, the following results in cats being set to 240, the value of the expression on the right of the comma:

cats = (17,240);

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.119.104.95