为自增(++)自减(--)运算符正名

学过C语言的朋友,相信你对“++i”,“- -i”,“i++”,“i- -”这样的表达式并不陌生,可是你真正明白其中的含义吗?

我发现在网上,充斥着对它们的误解,或者说似是而非的,似懂非懂的理解。我先举例一二。
一个来自于网上的例子(代码排版我修改了一下,这样符合我的阅读习惯):

#include <stdio.h>

int main(void)
{
    int a = 10;
    int b = 20;
    int c = 30;
    int d = 40;

    int a1,b1,c1,d1;

    a1 = ++a;
    b1 = b++;
    c1 = --c;
    d1 = d--;

    printf("a=%d, a1=%d\n", a, a1);
    printf("b=%d, b1=%d\n", b, b1);
    printf("c=%d, c1=%d\n", c, c1);
    printf("d=%d, d1=%d\n", d, d1);

    return 0;
}

输出结果:
a=11, a1=11
b=21, b1=20
c=29, c1=29
d=39, d1=40
文中是这样解释的:

a、b、c、d 的输出结果相信大家没有疑问,下面重点分析a1、b1、c1、d1:

1) 对于a1=++a,先执行++a,结果为11,再将11赋值给a1,所以a1的最终值为11。而a经过自增,最终的值也为11。

2) 对于b1=b++,b的值并不会立马加1,而是先把b原来的值交给b1,然后再加1。b原来的值为20,所以b1的值也就为20。而b经过自增,最终值为21。

3) 对于c1=- -c,先执行- -c,结果为29,再将29赋值给c1,所以c1的最终值为29。而c经过自减,最终的值也为29。

4) 对于d1=d- -,d的值并不会立马减1,而是先把d原来的值交给d1,然后再减1。d原来的值为40,所以d1的值也就为40。而d经过自减,最终值为39。

可以看出:
a1=++a; 会先进行自增操作,再进行赋值操作;
而b1=b++; 会先进行赋值操作,再进行自增操作。
c1=- -c; 和 d1=d- -; 也是如此。

网上还有这样的理解:

如果++或- -放在操作数前面就先进行自增或自减,再进行其他运算;
如果++或- -放在操作数后面就先进行其他运算,再进行自增或自减。

我觉得,虽然按照上文的解释可以分析出正确的答案,但是不够“专业”。

请看比较专业的解释(以++为例):
后缀递增

一个基本表达式(用E表示)的后面加上运算符“++”,就可以构成后缀递增表达式。 例如:

int i=0;
int j=0;
j = i++; //合法
int *p = &i;
(*p)++; //合法

后缀递增表达式的结果不是左值,它的值是E所指示的对象在递增操作前的原值,而不是递增后的新值;

后缀递增是具有副作用的表达式,这个副作用会修改E所指示的对象,将它的存储值变为表达式E+1的值;

E要求是实数类型或者指针类型,而且必须是可以修改的左值,所以像“250++”这样的表达式是非法的;

后缀递增表达式的结果类型和E的类型相同。

特别要指出:后缀++运算符的值的计算和它的副作用有确定的前序和后序关系,也就是说是先计算和得到后缀运算符++的值(这也是整个后缀递增表达式的值),再修改其操作数的存储值。

int i=0;
int j=1;
j = i++;

对于j = i++;
是要把i++这个表达式的值赋值给j; 而i++这个表达式的值是i所指示的对象在递增操作前的原值(也就是0),所以这条语句执行后,j=0;
同时,i++这个表达式是有副作用的,副作用就是i的存储值增加1,于是i变为1;

需要强调的是,i++这个表达式的值的计算和i的递增是有先后顺序的:先计算i++这个表达式的值 (=0),再递增i (递增后i=1).

前缀递增
运算符++加上一个表达式E,即可构成前缀递增表达式。
例如:

int a[2] = {3, 4};
int *p = a;
++a[0]; //合法
++p;   //合法

前缀递增表达式的结果不是左值,它的值是E所指示的对象在递增操作后的新值,即它在数值上等于表达式E+1的值;

前缀递增是具有副作用的表达式,这个副作用会修改E所指示的对象,将它的存储值变为表达式E+1的值;

E要求是实数类型或者指针类型,而且必须是可以修改的左值,所以像++++i这样的表达式是非法的;

前缀递增表达式的结果类型和E的类型相同。

在语义上,前缀递增表达式++E等价于表达式E += 1;

(完)

参考资料:《标准C语言指南》(李忠,电子工业出版社)

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值