深刻理解经典问题:i++与++i

一、printf函数参数顺序问题。

1、printf函数的参数的执行顺序问题:我们经常使用printf函数,由于本次实验是在linux下的gcc编译环境下进行,所以对于printf函数的参数,其结果也只使用与当前环境。可先观察例子:

    int i = 1;
    printf("i++= %d, i++ = %d, i++ = %d\n",i++, i++, i++);

运行结果为:

i++= 3, i++ = 2, i++ = 1

说明了printf的参数是先从右边到左边执行,但是,使用%d读取时并不是边运算边读取的,而是先把右边参数表达式处理成为一个数,然后再执行“”里面的内容顺序挨个%d读取。这里就是先从右到左依次执行i++,然后再从“”读取,当然是3,2,1了。


二、i++问题。

1、i++与++i的问题我们经常讨论,按照书本,

(1)i++就是先执行其它语句,然后再自增,如:a = i++; 则是执行相当于a = i; i = i+1;(最后再进行自增,也叫先人后己)

(2)若:a = ++i; 则是执行i = i+1; a = i。(一开始就自增,也叫先己后人)

但是其中容易产生陷阱,看以下一个简单的例子:

    int i = 1;
    printf("i++ = %d, i = %d\n",i++, i);

其运行结果为:

i++ = 1, i = 2

这个结果并不会出乎我们的意料,参数i++的结果为1(先执行其它表达式,最后再自增,先人后己),执行完所有参数以后,最后再执行i = i+1;因此i的结果为2,i++的结果为1。


2、再看一个例子:

    int i = 1;
    printf("i++= %d, i++ = %d, i = %d\n",i++, i++, i);

运行结果为:

i++= 2, i++ = 1, i = 3

这次结果就出乎意料了,但是仔细分析,也完全符合逻辑,按照参数运算的右到左,i初始值为1,因此i++(1++)的值也为1,执行完i++以后就执行i=i+1了(先人后己),i的值就为2了,然后再遇到一个i++,因此(2++)的结果是2,最后再执行一次i=i+1(先人后己),i的结果就变成了3了,最后,%d对三个表达式的结果进行读取,依次就是
2, 1, 3了。


三、++i问题。

1、有了前面的基础,后面问题的分析就轻松多了,++i是先自增再执行其它表达式,可以理解为先己后人,对于其分析也如此,看一下例子:

    int i = 1;
    printf("++i = %d, ++i = %d, i = %d\n",++i, ++i, i);

结果为:

++i = 3, ++i = 3, i = 3

按照上面的分析,从右到左,i的依次先自增,并且++i执行自增再执行其它,所以从右到左第一次++i时,i为2,第二次时为3,后面执行的++i可以覆盖前面的++i(因为其是先自增,可以理解++i是与i几乎同步的,因为每次执行++i的第一步必先自增,所以从++i中%d读取的结果实质是i)所以输出结果为3, 3, 3。


2、再看一个例子:

    int i = 1;
    printf("++i = %d, i++ = %d, ++i = %d,i++ = %d, i = %d\n",++i,i++,++i,i++,i);

结果为:

++i = 5, i++ = 3, ++i = 5, i++ = 1, i = 5

按照分析:
(1)从右到左,i初始化为1,经历i++以后,1++为1,执行完以后i为2;
(2)再执行++i,++2结果为3,同时i也为3;
(3)再i++,3++为3,执行完以后i为4;
(4)最后再执行++i,++4为5同时i也为5;同时前面的++i(实质上是i)也会被覆盖,为5。


四、总结。
总的来说,++i实质上是立刻将自身自增,所以作为printf函数的参数时,后面运算的++i会覆盖前面的++i,其值是跟i自身同步的;i++是先执行其它再自增,所以并不会覆盖。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值