The increment and decrement operators are unary. The operand
must be a scalar lvalue — it is illegal to increment or
decrement a constant, structure, or union. It is legal to increment
or decrement pointer variables, but the meaning of adding 1 to a
pointer is different from adding 1 to an arithmetic value. This
is described in “Pointer Operators (*,
->, &)”.
There are two forms for each of the operators: postfix and
prefix. Both forms increment or decrement the appropriate variable,
but they do so at different times. The statement ++i
(prefix form) increments i
before using its value, while i++
(postfix form) increments it after its value has been used. This
difference can be important to your program.
The postfix increment and decrement operators fetch the current
value of the variable and store a copy of it in a temporary location.
The compiler then increments or decrements the variable. The temporary
copy, which has the variable"s value before it was modified,
is used in the expression.
In many cases, you are interested only in the side effect,
not in the result of the expression. In these instances, it doesn"t
matter whether you use postfix or prefix.
You need to be careful, however, when you use the increment
and decrement operators within an expression.
Standalone Increment
Decrement Expressions
For example, as a stand-alone assignment or as the
third expression in a for loop, the side effect is the same whether
you use the prefix or postfix versions. The statement
is equivalent to
Similarly, the statement
for (j = 0; j <= 10; j++)
|
is equivalent to
for (j = 0; j <= 10; ++j)
|
Using Increment and
Decrement within Expressions
Consider the following function that inserts newlines into
a text string at regular intervals.
#include <stdio.h> void break_line(int interval) { int c, j=0; while ((c = getchar()) != "\n") { if ((j++ % interval) == 0) printf("\n"); putchar(c); } }
|
This works because the postfix increment operator is used.
If you use the prefix increment operator, the function breaks the
first line one character early.
Side Effects of the Increment
and Decrement Operators
The increment and decrement operators and the assignment operators
cause side effects. That is, they not only result in a value, but
they change the value of a variable as well. A problem with side
effect operators is that it is not always possible to predict the
order in which the side effects occur. Consider the following statement:
The C language does not specify which multiplication operand
is to be evaluated first. One compiler may evaluate the left operand
first, while another evaluates the right operand first. The results
are different in the two cases. If j equals 5, and the left operand
is evaluated first, the expression will be interpreted as
x = 5 * 5; /* x is assigned 25 */
|
If the right operand is evaluated first, the expression becomes
x = 6 * 5; /* x is assigned 30 */
|
Statements such as this one are not portable and should be
avoided. The side effect problem also crops up in function calls
because the C language does not guarantee the order in which arguments
are evaluated. For example, the function call
is not portable because compilers are free to evaluate the
arguments in any order they choose.
To prevent side effect bugs, follow this rule: If you use
a side effect operator in an expression, do not use the affected
variable anywhere else in the expression. The ambiguous expression
above, for instance, can be made unambiguous by breaking it into
two assignments:
Precedence of Increment and Decrement
Operators
The increment and decrement operators have the same
precedence, but bind from right to left. So the expression
is evaluated as
This expression is illegal because j++
is not an lvalue as required by the
operator. In general, you should avoid using multiple increment
or decrement operators together.