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

C语言printf中的自增运算符

作者头像
全栈开发日记
发布于 2022-05-13 06:43:20
发布于 2022-05-13 06:43:20
86600
代码可运行
举报
文章被收录于专栏:全栈开发日记全栈开发日记
运行总次数:0
代码可运行

先看个例子:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
int i=1;
printf("%d====%d",++i,i++);

输出结果:3====1

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

解析:

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

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

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

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// 在printf中,运算规则变为从右向左,输出规则为从左向右

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

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

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

再看一个例子:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
int i=1;
printf("%d====%d====%d",i++,++i,++i);

解析过程:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
/* 运算部分,从右向左*/
++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
代码运行次数:0
运行
AI代码解释
复制
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
代码运行次数:0
运行
AI代码解释
复制
addl $1, -4(%rbp) // 将i的值增加1赋值给i, i=6
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-03-16,如有侵权请联系 cloudcommunity@tencent.com 删除

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

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

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

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
计算机系统基础作业
void func(int *xptr, int *yptr, int *zptr);
一只胡说八道的猴子
2020/12/16
1.6K0
程序员C语言快速上手——基础篇(三)
上一节已经讲过,由于C语言中,整型的实际长度和范围不固定的问题,会导致C语言存跨平台移植的兼容问题,因此,C99标准中引入了stdint.h头文件,有效的解决了该问题。
arcticfox
2019/06/26
1.2K0
程序员C语言快速上手——基础篇(三)
AT&T汇编语言与GCC内嵌汇编简介
1 AT&T 与INTEL的汇编语言语法的区别 1.1大小写 1.2操作数赋值方向 1.3前缀 1.4间接寻址语法 1.5后缀 1.6指令
Java架构师必看
2021/03/22
2.2K0
深入理解计算机系统(3.3)------操作数指示符和数据传送指令
本文介绍了汇编语言中的操作数指示符,包括操作数类型、寄存器、内存和表达式。同时,本文还详细介绍了数据传送指令、算术和逻辑操作指令、字符串操作指令和其他指令,为读者提供了全面的汇编语言指令知识。
IT可乐
2018/01/04
1.5K0
深入理解计算机系统(3.3)------操作数指示符和数据传送指令
深入理解计算机系统(3.8)------数组分配和访问
该文介绍了计算机程序中数组的使用,包括数组分配、访问以及数组嵌套和变长数组。
IT可乐
2018/01/04
1K0
深入理解计算机系统(3.8)------数组分配和访问
C/C++ 学习笔记三(函数)
导语 函数在编程语言中可谓“头等公民”,理解函数的实现原理,函数的一些方法论对于编程非常有好处。 我将从函数的实现原理以及编写函数的一些建议两个的角度来重新认识一下C、C++中的函数。 那具体函数在汇
Celebi
2017/08/21
1.2K0
C/C++ 学习笔记三(函数)
深入理解计算机系统(3.4)------算术和逻辑操作
本文介绍了计算机系统中的算术和逻辑操作,包括加法、减法、乘法、除法和取模等基本算术操作,以及与、或、非和移位等逻辑操作。还介绍了 LEA、ADD、SUB、IMUL、XOR、OR、AND、INC、DEC、NEG、NOT 和 SAL、SHL、SAR、SHR 等指令。
IT可乐
2018/01/04
1K0
深入理解计算机系统(3.4)------算术和逻辑操作
计算机系统课程作业
如下为一个c语言程序中的函数及其在32位系统下编译得到的汇编语言程序代码,请详细说明每条汇编语句的意义,并将这个函数补充完整。
Heeler-Deer
2023/02/22
3380
计算机指令考前小记
汇编指令movw 4(%ebp),%ax的RTL语言为:R[ax] <- M[R[ebp]+4]
WuShF
2023/11/13
3790
计算机指令考前小记
程序的机器级表示
预处理阶段:预处理器cpp根据编译文件以“#”开头的命令,读取系统头文件stdio.h(.h结尾的表示头文件,.c表示可执行文件)的内容,并把它插入到程序文本中,得到一个新的文件。
_春华秋实
2019/02/22
6590
程序的机器级表示
__asm__ volatile 之 C语言嵌入式汇编
或者: para = 0x04 movl $para, %ebx 指令执行的结果是将立即数04h装入寄存器ebx。
用户1147447
2019/05/26
12.8K0
2.1 C++自增自减运算符
在使用i之后,先让i的值加1,比如上述代码,执行j=i++之后,j的值是3,i的值才是4
小林C语言
2020/10/30
7080
go语言调度器源代码情景分析之五:汇编指令
汇编语言是每位后端程序员都应该掌握的一门语言,因为学会了汇编语言,不管是对我们调试程序还是研究与理解计算机底层的一些运行原理都具有非常重要的作用,所以建议有兴趣的读者可以多花点时间把它学好。
阿波张
2019/06/24
1.2K0
go语言调度器源代码情景分析之五:汇编指令
xv6(21) 内联汇编
内联汇编,顾名思义,一种语言的内部使用汇编,一般的语言是不能直接操作寄存器的,而汇编可以,所以在这种语言内部以某种方式嵌入汇编代码来提升能力,一般来说也就是 c/c++ 使用内联汇编比较多,本文用的 c 语言来叙述,废话不再多说,直接来看。
rand_cs
2023/12/10
2780
内联汇编很可怕吗?看完这篇文章,终结它!
在 Linux 代码中,经常可以看到在 C 代码中,嵌入部分汇编代码,这些代码要么是与硬件体系相关的,要么是对性能有关键影响的。
IOT物联网小镇
2021/05/13
2.4K0
内联汇编很可怕吗?看完这篇文章,终结它!
Go 语言汇编入门
在 JVM 中,字节码可以帮我们搞清楚很多编译执行的细节, 为了搞清楚 go 语言底层的语法糖和原理,需要对底层的汇编知识有深入的了解。汇编其实没有想象中那么复杂,其实原理上来说跟 Java 字节码差不多,只是资料很少,因为更接近系统底层,阅读的难度相对而言更大一些。
挖坑的张师傅
2022/05/13
9670
Go 语言汇编入门
C语言再学习 — 关键字volatile
上周确实事情挺多的,年会、公司聚餐,一到过年就有忙不完的事分心。还好C语言再学习总结的已经差不多了,年前也不展开别的了,接下来这十几天、总结几篇典型的面试题吧。
全栈程序员站长
2022/09/19
3960
C语言再学习 — 关键字volatile
冷知识:达夫设备(Duff's Device)效率真的很高吗?
相信大家写业务逻辑的时候,都是面向if、else、for、while、switch编程。但是你见过switch嵌套do..while吗?
李肖遥
2020/07/06
1.1K0
函数战争(栈帧)之创建与销毁(c语言)(vs2022)
C语言中,每个栈帧对应着一个未运行完的函数。栈帧中保存了该函数的返回地址和局部变量。栈帧也叫过程活动记录,是编译器用来实现过程函数调用的一种数据结构。
2024/04/30
1780
函数战争(栈帧)之创建与销毁(c语言)(vs2022)
C/C++:堆栈面面观
在数据结构中,我们也听过栈和堆这两种数据结构,当然和我本文要讲的东西是不同的概念。不过数据结构中的栈(算法、数学意义上的一种抽象),和本文中的栈(实际存在的存储区)有一共同之处就是FILO —— 先入后出。但是数据结构中的堆和我们本文中的堆则是毫不相干。
果冻虾仁
2021/12/08
5560
C/C++:堆栈面面观
相关推荐
计算机系统基础作业
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验