前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >C语言printf中的自增运算符

C语言printf中的自增运算符

作者头像
全栈开发日记
发布2022-05-13 14:43:20
8110
发布2022-05-13 14:43:20
举报
文章被收录于专栏:全栈开发日记

先看个例子:

代码语言:javascript
复制
int i=1;
printf("%d====%d",++i,i++);

输出结果:3====1

是不是很意外,我开始也很意外。。。请看解析。

解析:

C语言中,++i表示先运算后赋值,i++表示先赋值后运算。这个知识点相信只要会点编程的人都知道。

而C语言中,printf中自增自减运算符却有另一片天地。其实上面例子如果将C语言代码换成汇编语言,能清晰的看出来代码的执行流程,只是放出来汇编代码怕是不懂汇编的就更懵了。

所以这里我就不放汇编了,直接用最通俗的方式记录我的理解。

代码语言:javascript
复制
// 在printf中,运算规则变为从右向左,输出规则为从左向右

/* 运算部分 */
// 由于运算是从右向左
i++ // 由于i++是先赋值后运算,会先将1赋值,最后这个位置输出肯定是1,运算后i=2
++i    // 上一步运算后i=2,++i是先运算后赋值,所以i=3。下面开始输出

/* 输出部分 */
// 输出是从左向右
++i    // 上面已经经过运算,所以这里输出i=3
i++ // 上面也说了,i++是先赋值后运算,所以这里输出为上面最初运算到这里的值i=1
    
// 所以输出3,1

PC端观看代码注释可能会更舒服一点。

再看一个例子:

代码语言:javascript
复制
int i=1;
printf("%d====%d====%d",i++,++i,++i);

解析过程:

代码语言:javascript
复制
/* 运算部分,从右向左*/
++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++的汇编代码:

代码语言:javascript
复制
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的汇编代码:

代码语言:javascript
复制
addl $1, -4(%rbp) // 将i的值增加1赋值给i, i=6
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-03-16,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 全栈开发日记 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 解析:
  • 再看一个例子:
  • 扩展汇编代码:
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档