5.5. Increment and Decrement OperatorsThe 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. Postfix Operators Return the Unincremented ValueThe 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 ExpressionThe 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 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! |