先看个例子:
int i=1;
printf("%d====%d",++i,i++);
输出结果:3====1
是不是很意外,我开始也很意外。。。请看解析。
C语言中,++i
表示先运算后赋值,i++
表示先赋值后运算。这个知识点相信只要会点编程的人都知道。
而C语言中,printf
中自增自减运算符却有另一片天地。其实上面例子如果将C语言代码换成汇编语言,能清晰的看出来代码的执行流程,只是放出来汇编代码怕是不懂汇编的就更懵了。
所以这里我就不放汇编了,直接用最通俗的方式记录我的理解。
// 在printf中,运算规则变为从右向左,输出规则为从左向右
/* 运算部分 */
// 由于运算是从右向左
i++ // 由于i++是先赋值后运算,会先将1赋值,最后这个位置输出肯定是1,运算后i=2
++i // 上一步运算后i=2,++i是先运算后赋值,所以i=3。下面开始输出
/* 输出部分 */
// 输出是从左向右
++i // 上面已经经过运算,所以这里输出i=3
i++ // 上面也说了,i++是先赋值后运算,所以这里输出为上面最初运算到这里的值i=1
// 所以输出3,1
PC端观看代码注释可能会更舒服一点。
int i=1;
printf("%d====%d====%d",i++,++i,++i);
解析过程:
/* 运算部分,从右向左*/
++i // 先运算后赋值,i=2=i+1
++i // 还是先运算后赋值,i=3=i+1
i++ // 先赋值后运算,所以输出i=3,再运算i=4=i+1
// 运算后的值为 i=4
/* 输出部分,从左向右*/
i++ // 运算之前,i=3,所以输出3
++i // 此时i=4,输出当前值 i=4
++i // 此时i=4,输出当前值 i=4
其实,如果运算过程中,遇到i++
这样需要先赋值后运算的情况,编译器会将运算前的值存储在寄存器中,以便在运算完成之后运行输出,所以后面输出的其实是寄存器中之前存储下来的值。
而像++i
这样先运算后赋值的情况则无需寄存器来保存运算之前的值,因为运算之前的值保存下来毫无意义,它会输出运算之后的值。
i--
和--i
同理。
i++
的汇编代码:
movl -4(%rbp), %eax // 将i赋值给ax寄存器, ax=5
leal 1(%rax), %edx // 将ax寄存器的值加1赋值给dx寄存器, dx=ax+1=6
movl %edx, -4(%rbp) // 将dx寄存器的值赋值给i, i=dx=6
++i
的汇编代码:
addl $1, -4(%rbp) // 将i的值增加1赋值给i, i=6
扫码关注腾讯云开发者
领取腾讯云代金券
Copyright © 2013 - 2025 Tencent Cloud. All Rights Reserved. 腾讯云 版权所有
深圳市腾讯计算机系统有限公司 ICP备案/许可证号:粤B2-20090059 深公网安备号 44030502008569
腾讯云计算(北京)有限责任公司 京ICP证150476号 | 京ICP备11018762号 | 京公网安备号11010802020287
Copyright © 2013 - 2025 Tencent Cloud.
All Rights Reserved. 腾讯云 版权所有