2.8 自增运算符与自减运算符
C 语言提供了两个用于变量递增与递减的特殊运算符
自增运算符 ++
使其操作数递增 1,自减运算符 --
使其操作数递减 1
我们经常使用 ++
运算符递增变量的值:
if (c == '\n')
++nl;
++
与 --
这两个运算符特殊的地方主要表现在:
它们既可以用作前缀运算符(用在变量前面,如 ++n
)也可以用作后缀运算符(用在变量后面,如 n++
)
在这两种情况下,其效果都是将变量 n
的值加 1
,但是,它们之间有一点不同
表达式 ++n
先将 n
的值递增 1
,然后再使用变量 n
的值,而表达式 n++
则是先使用变量 n
的值,然后再将 n
的值递增 1
也就是说,对于使用变量 n
的值的上下文来说,++n
和 n++
的效果是不同的
如果 n
的值为 5
,那么 x = n++;
执行后的结果是将 x
的值置为 5
,而 x = ++n;
将 x
的值置为 6
这两条语句执行完成后,变量 n
的值都是 6
自增与自减运算符只能作用于变量,类似于表达式 (i + j)++
是非法的
在不需要使用任何具体值且仅需要递增变量的情况下,前缀方式和后缀方式的效果相同:
if (c == '\n')
nl++;
但在某些情况下需要根据具体需求来决定使用哪个
例如,考虑下面的函数 squeeze(s, c)
,它删除字符串 s
中出现的所有字符 c
:
/* 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';
}
每当出现一个不是 c
的字符时,该函数把它拷贝到数组中下标为 j
的位置
随后才将 j
的值增加 1
,以准备处理下一个字符
其中的 if
语句完全等价于下列语句:
if (s[i] != c) {
s[j] = s[i];
j++;
}
在第 1 章中编写的函数 getline
是类似结构的另外一个例子,可以将该函数中的 if
语句:
if (c == '\n') {
s[i] = c;
++i;
}
用下面这种更简洁的形式代替:
if (c == '\n')
s[i++] = c;
考虑标准函数 strcat(s, t)
,它将字符串 t
连接到字符串 s
的尾部
函数 strcat
假定字符串 s
中有足够的空间保存这两个字符串连接的结果
下面的函数没有任何返回值(标准库中的该函数返回一个指向新字符串的指针):
/* 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 */
;
}
在将 t
中的字符逐个拷贝到 s
的尾部时,变量 i
和 j
使用的都是后缀运算符 ++
从而保证在循环过程中 i
与 j
均指向下一个位置