先来看一个例子:

#inlcude <stdio.h>int main()
{int i = 0;printf("%d,%d,%d\n", i++, --i, i++);
}

有一部分人认为打印的结果应该是0,0,0.
下面是VS2013运行出来的结果:

大家心里肯定会有疑惑,为什么会是这样的结果?我们不妨先来分析一下。

大家都很清楚,printf()这个函数在打印参数内容时,是从右往左的,当有多个参数时(依次入栈的原因),printf()函数执行时是遍历一个参数打印一个参数呢?还是先遍历一遍参数然后在依次打印呢?大家有没有考虑过呢?

我们不妨假设printf()函数执行时遍历一个参数打印一个参数:
1、首先处理的是最右边的表达式i++,打印出其结果为0,而后i的值变为1;
2、接下来处理的是表达式–i,由于i的值已变为1,所以打印的结果为0,而后i的值变为0;
3、最后处理的是最左边的表达式i++,此时i值为0,所以打印的结果为0,而后i的值变为1。
通过上面的分析,可以看出打印的结果是0,0,0,可真的是这样吗?
我们先来看一下上述代码的汇编代码:

1、在红色框里,处理表达式i++时,先通过寄存器eax先将内存中i的值(为0)放入一个系统临时开辟的整型大小的地址空间(ptr [ebp-0D0h]开始的地址空间)中保存起来,之后通过寄存器ecx将内存中i的值加1再将加1后的结果放到i原来的内存中去,此时内存中i的值变为1;

2、红色框里的指令是用来处理表达式–i的,可以看出在处理表达式–i时,是直接通过寄存器edx将内存中i的值减1之后再将减1后的结果放到i原来的内存中去,此时i的值变为0.;

3、接下来处理最左边的表达式i++,可以看出红色框内的代码和处理最最右边的表达式i++的代码几乎一样,只是存放i值的地址不一样,这次是通过寄存器eax将i的值0存放到内存dword ptr [ebp-0D4h]开始的内存单元中。

接下来便是入栈了:

第一步是通过寄存器edx将内存ptr [ebp-0D0h]开始的连续四个地址空间的值入栈,该值为0;

第二步是将内存中i的值通过寄存器eax入栈,此时i的值为1;

第三步通过通过寄存器edx将内存ptr [ebp-0D4h]开始的连续四个地址空间的值入栈,该值为0。

之后系统将当前指令的下一条指令的地址入栈(现场保护),然后调用printf()函数依次打印上述表达式的结果,得到的结果是0,1,0

通过上面的分析,相信大家对i++,i–,++i,–i以及printf()函数打印的过程已经深刻理解了。

最后,总结一下:
对于前置++、–处理的时候系统会直接操作不产生临时量,只需三条代码;对于后置++、–处理的时候会先产生一个临时量,而后通过临时量返回结果,需要五条代码,所以在同样的环境下前置++或–要比后置++或–效率要高。
对于printf()函数的处理过程,我们可以看到,是先将参数从右到左遍历一遍,最后才执行打印操作,而不是遍历一个打印一个。

对i++,i--,++i,--i深刻认识以及printf()函数打印的过程相关推荐

  1. KEIL 调试经验总结

    来源:公众号[鱼鹰谈单片机] 作者:鱼鹰Osprey ID   :emOsprey 通过前面的多篇文章(已整理成专辑)我们已经了解了很多的 KEIL 调试方法,但是到底该怎么使用这些方法呢?这篇文章将 ...

  2. 哈尔滨工业大学2023春 计算机系统大作业 程序人生-Hello’s P2P

    摘要 本文以一个简单的hello.c程序为例,介绍了程序在Linux系统上的一生.通过使用Linux上的各种工具,详细揭露了hello.c文件从变为到可执行文件程序存到硬盘开始,之后再从载入内存进程, ...

  3. 哈工大2022春CSAPP大作业

    摘  要 本文对hello程序从编写完成开始到最终运行结束的整个过程进行了详细的介绍.涵盖了源文件hello.c经过预处理,编译,汇编,链接一步步变成可执行文件的每一阶段.然后为了执行hello程序, ...

  4. SySeVR中数据集漏洞类型以及对应漏洞代码位置分析

    一.前言 最近看了几篇相关的论文,发现开源的数据集虽然大都来自SARD和NVD,但是每个数据集的组织形式和内容形式都不太一样,加上漏洞种类繁多,最近在复现提取漏洞标签算法时,不知道该如何去匹配到多种漏 ...

  5. 找工作之深信服科技笔试

    下午五点多刚从湖南大学回来,下午在那边参加了深信服科技的笔试,又被打击了,估计连面试的机会都没了. 由于昨晚恶补了一下深信服往年的笔试题,现在还昏昏欲睡呢,唉!像我这样的半路出家的(我的专业是通信工程 ...

  6. linux内核功能有,好消息!LINUX内核2.6.18终于支持实时功能了

    LINUX内核2.6.18终于支持实时功能了,这是个好消息.当LINUX实时功能加强后,它在嵌入式系统的应用就会更广泛了.在这一版发布前,为了使嵌入式系统的LINUX具有实时特性,需要给标准和LINU ...

  7. 中国AI已进入迷茫阶段!从技术到科学,AI该何去何从?

    作者:金榕,阿里巴巴达摩院副院长.原密歇根州立大学终身教授 引言 如果从达特茅斯会议起算,AI已经走过65年历程,尤其是近些年深度学习兴起后,AI迎来了空前未有的繁荣.不过,最近两年中国AI热潮似乎有 ...

  8. DeepMind让AI变身天才数学家!首次提出两大数学猜想,登Nature封面

    点击上方"视学算法",选择加"星标"或"置顶" 重磅干货,第一时间送达 来源丨新智元 编辑丨极市平台 导读 12月2日,DeepMind用A ...

  9. 64位程序怎么判断指针是否有效_C 语言指针怎么理解?

    注: 看完这篇一定会让你理解透彻指针的本质 是的,这一篇的文章主题是「指针与内存模型」 说到指针,就不可能脱离开内存,学会指针的人分为两种,一种是不了解内存模型,另外一种则是了解. 不了解的对指针的理 ...

  10. 20172328《程序设计与数据结构》实验二:树

    20172328<程序设计与数据结构>实验二:树 课程:<软件结构与数据结构> 班级: 1723 姓名: 李馨雨 学号:20172328 实验教师:王志强老师 实验日期:201 ...

最新文章

  1. android 修改编译内核源码 对抗反调试
  2. C/C++中extern关键字
  3. windows 8 及vs2012 下载
  4. 合并多个Word文档
  5. 树莓派下的apache
  6. 来给你20个优秀的......前端轮播图插件
  7. 当月、 时间_为什么当月增加的固定资产下月计提折旧?点破了,就很容易!...
  8. 网络商务信息与计算机的关系,计算机与电子商务的关系,
  9. android 插入gif,android – Gboard:在EditText上启用GIF插入
  10. Java面向对象(继承、抽象类)
  11. 字符串资源的内部格式
  12. sharepoint 在Visual Studio设置其他页面的加载标签
  13. P106魔改1060
  14. 微信开门,给你简单极致的开门体验!
  15. Arduino Adafruit GFX图形库介绍(三)- 图形基本元素
  16. 警惕Linux的传销投机属性,恢复建立契约商业化社会秩序。
  17. 考研二战日记-第11天——高数2.1 导数概念
  18. php 半角 全角 转换,PHP半角/全角转换函数
  19. 2021计算机excel,excel2021版本
  20. 堪称神级的阿里巴巴“高并发”教程《基础+实战+源码+面试+架构》

热门文章

  1. 华为钱包扫码云闪付_华为钱包、云闪付,NFC支付要这样使用!!!-已回复
  2. NEURAL MACHINE TRANSLATION BY JOINTLY LEARNING TO ALIGN AND TRANSLATE-论文翻译
  3. Macbook Pro拆机清灰体验
  4. 当更高性能来到平板 — ThinkPad X1 Tablet Evo 长测
  5. Redis高频面试题(欢迎来学习讨论)
  6. 彼时彼刻,正如此时此刻——评《让×××飞》
  7. Solr---string类型的docValues属性、stored属性
  8. lae界面开发工具入门之介绍五--秘籍篇-杂项
  9. 数据挖掘实验:使用 Hadoop 实现 WordCount 应用
  10. 架构师?so easy