Section 5.5. Increment and Decrement Operators


5.5. Increment and Decrement Operators

The increment (++) and decrement (--) operators provide a convenient notational shorthand for adding or subtracting 1 from an object. There are two forms of these operators: prefix and postfix. So far, we have used only the prefix increment, which increments its operand and yields the changed value as its result. The prefix decrement operates similarly, except that it decrements its operand. The postfix versions of these operators increment (or decrement) the operand but yield a copy of the original, unchanged value as its result:

      int i = 0, j;      j = ++i; // j = 1, i = 1: prefix yields incremented value      j = i++; // j = 1, i = 2: postfix yields unincremented value 

Because the prefix version returns the incremented value, it returns the object itself as an lvalue. The postfix versions return an rvalue.

Advice: Use Postfix Operators Only When Necessary

Readers from a C background might be surprised that we use the prefix increment in the programs we've written. The reason is simple: The prefix version does less work. It increments the value and returns the incremented version. The postfix operator must store the original value so that it can return the unincremented value as its result. For ints and pointers, the compiler can optimize away this extra work. For more complex iterator types, this extra work potentially could be more costly. By habitually favoring the use of the prefix versions, we do not have to worry if the performance difference matters.


Postfix Operators Return the Unincremented Value

The postfix version of ++ and -- is used most often when we want to use the current value of a variable and increment it in a single compound expression:

      vector<int> ivec;           // empty vector      int cnt = 10;      // add elements 10...1 to ivec      while (cnt > 0)          ivec.push_back(cnt--);  // int postfix decrement 

This program uses the postfix version of -- to decrement cnt. We want to assign the value of cnt to the next element in the vector and then decrement cnt before the next iteration. Had the loop used the prefix version, then the decremented value of cnt would be used when creating the elements in ivec and the effect would be to add elements from 9 down to 0.

Combining Dereference and Increment in a Single Expression

The following program, which prints the contents of ivec, represents a very common C++ programming pattern:

      vector<int>::iterator iter = ivec.begin();      // prints 10 9 8 ... 1      while (iter != ivec.end())          cout << *iter++ << endl; // iterator postfix increment 

The expression *iter++ is usually very confusing to programmers new to both C++ and C.



The precedence of postfix increment is higher than that of the dereference operator, so *iter++ is equivalent to *(iter++). The subexpression iter++ increments iter and yields a copy of the previous value of iter as its result. Accordingly, the operand of * is a copy of the unincremented value of iter.

This usage relies on the fact that postfix increment returns a copy of its original, unincremented operand. If it returned the incremented value, we'd dereference the incremented value, with disastrous results: The first element of ivec would not get written. Worse, we'd attempt to dereference one too many elements!

Advice: Brevity Can Be a Virtue

Programmers new to C++ who have not previously programmed in a C-based language often have trouble with the terseness of some expressions. In particular, expressions such as *iter++ can be bewilderingat first. Experienced C++ programmers value being concise. They are much more likely to write

      cout << *iter++ << endl; 

than the more verbose equivalent

      cout << *iter << endl;      ++iter; 

For programmers new to C++, the second form is clearer because the action of incrementing the iterator and fetching the value to print are kept separate. However, the first version is much more natural to most C++ programmers.

It is worthwhile to study examples of such code until their meanings are immediately clear. Most C++ programs use succinct expressions rather than more verbose equivalents. Therefore, C++ programmers must be comfortable with such usages. Moreover, once these expressions are familiar, you will find them less error-prone.


Exercises Section 5.5

Exercise 5.15:

Explain the difference between prefix and postfix increment.

Exercise 5.16:

Why do you think C++ wasn't named ++C?

Exercise 5.17:

What would happen if the while loop that prints the contents of a vector used the prefix increment operator?




C++ Primer
C Primer Plus (5th Edition)
ISBN: 0672326965
EAN: 2147483647
Year: 2006
Pages: 223
Authors: Stephen Prata

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net