HPlogo HP C/HP-UX Reference Manual: Version A.05.55.02 > Chapter 5 Expressions and Operators

Increment and Decrement Operators (++, --)

» 

Technical documentation

Complete book in PDF

 » Table of Contents

 » Index

Syntax

lvalue++

Increments the current value of lvalue after lvalue has been referenced.

lvalue--

Decrements the current value of lvalue after lvalue has been referenced.

++lvalue

Increments the current value of lvalue before lvalue is referenced.

--lvalue

Decrements the current value of lvalue after lvalue has been referenced.

Arguments

lvalue

Any previously declared integer or pointer lvalue. Although lvalue can be a pointer variable, it cannot be a pointer to a function.

Description

The increment operator (++) adds 1 to its operand. The decrement operator (--) subtracts 1 from its operand.

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 (*, ->, &)”.

Postfix and Prefix Forms

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

x++;

is equivalent to

++x;

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:

x = j * j++;

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

f(a, a++)

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:

x = j * j;
++j;

Precedence of Increment and Decrement Operators


The increment and decrement operators have the same precedence, but bind from right to left. So the expression

--j++

is evaluated as

--(j++)

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.

Examples

i=k--; /* Stores the value of k in i then decrements k. */
j=l++; /* Stores the value of l in j then increments l. */
i=--k; /* Decrements k then stores the new value of k in i. */
j=++l; /* Increments l then stores the new value of l in j. */

The following example uses both prefix and postfix increment and decrement operators:

#include <stdio.h>
int main(void)
{
int j = 5, k = 5, l = 5, m = 5;
printf("j: %d\t k: %d\n", j++, k--);
printf("j: %d\t k: %d\n", j, k);
printf("l: %d\t m: %d\n", ++l, --m);
printf("l: %d\t m: %d\n", l, m);
}

The result is as follows:

j: 5 k: 5
j: 6 k: 4
l: 6 m: 4
l: 6 m: 4

The results show that the initial values of j and k are used in the first printf(). They also show that l and m are incremented and decremented, respectively, before the third printf() call.

© Hewlett-Packard Development Company, L.P.