Increment and Decrement Operators
C provides two unusual operators for incrementing and decrementing variables. The increment operator ++
adds 1 to its operand, while the decrement operator --
subtracts 1. We have frequently used ++
to increment variables, as in:
if (c == '\n') ++nl;
The unusual aspect is that ++
and --
may be used either as prefix operators (before the variable, as in ++n), or postfix operators (after the variable: n++). In both cases, the effect is to increment n. But the expression ++n increments n before its value is used, while n++ increments n after its value has been used. This means that in a context where the value is being used, not just the effect, ++n and n++ are different. If n is 5, then:
x = n++;
sets x to 5, but:
x = ++n;
sets x to 6. In both cases, n becomes 6. The increment and decrement operators can only be applied to variables; an expression like (i+j)++
is illegal.
In a context where no value is wanted, just the incrementing effect, as in:
if (c == '\n')
nl++;
prefix and postfix are the same. But there are situations where one or the other is specifically called for. For instance, consider the function squeeze(s,c)
, which removes all occurrences of the character c from the string s.
/* squeeze: delete all c from s */
void squeeze(char s[], int c) {
int i, j;
for (i = j = 0; s[i] != '\0'; i++)
if (s[i] != c)
s[j++] = s[i];
s[j] = '\0';
}
Each time a non-c occurs, it is copied into the current j position, and only then is j incremented to be ready for the next character. This is exactly equivalent to:
if (s[i] != c) {
s[j] = s[i];
j++;
}
Another example of a similar construction comes from the getline
function that we wrote in Chapter 1, where we can replace
if (c == '\n') {
s[i] = c;
++i;
}
by the more compact
if (c == '\n')
s[i++] = c;
As a third example, consider the standard function strcat(s,t)
, which concatenates the string t to the end of string s. strcat
assumes that there is enough space in s to hold the combination. As we have written it, strcat
returns no value; the standard library version returns a pointer to the resulting string.
/* strcat: concatenate t to end of s; s must be big enough */
void strcat(char s[], char t[]) {
int i, j;
i = j = 0;
while (s[i] != '\0') /* find end of s */
i++;
while ((s[i++] = t[j++]) != '\0') /* copy t */
;
}
As each member is copied from t to s, the postfix ++ is applied to both i and j to make sure that they are in position for the next pass through the loop.
Exercise 2-4. Write an alternative version of squeeze(s1,s2) that deletes each character in s1 that matches any character in the string s2.
Exercise 2-5. Write the function any(s1,s2)
, which returns the first location in a string s1 where any character from the string s2 occurs, or -1 if s1 contains no characters from s2. (The standard library function strpbrk
does the same job but returns a pointer to the location.)