首先看几种情况

1、

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

运行结果为:2,1

这与编译器有关,通过汇编可以很清楚的看到

第一步:把i的值存入缓存器[ebp-0E8h]=1;

第二步:i值加1,i=i+1=2;

第三步:把i的值存入缓存器[ebp-0ECh]=2;

第四步:i值减1,i=i-1=1;

第五步:把缓存器[ebp-0E8h]=1,入栈

第六步:把缓存器[ebp-0ECh]=2,入栈

故,打印输出为 2,1

总结:

由++或者--运算的顺序是从右向左,故先计算i++,i++在计算过程中会产生缓存区,返回的值就是缓存区的值,既是在加1之前需要先备份,这里的缓存区地址就是[ebp-0E8h]=1,

之后,i=i+1=2;

同理,第二个表达式的缓存区[ebp-0ECh]=2,

之后,i=i-1=1;

然后把第一,第二个表达式的返回值分别入栈【1,2】故输出为 2 1;

2、

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

第一步:i值加1,i=i+1=2;

第二步:把i的值存入缓存区[ebp-0E8h]=2;

第三步:i值加1,i=i+1=3;

第四步:把i=3,入栈

第五步:把缓存区[ebp-0E8h]=2,入栈

故,输出为2,3

总结:

由++或者--运算的顺序是从右向左,故先计算++i,++i的返回值为i本身,本应该是2,但是后面的运算却影响i的值,另外printf输出流的缓存栈是在所有表达式计算完后再入栈的,只需要知道首先入栈的是i的地址里面存的值,

下面该表达式i++,i++在计算过程中会产生缓存区,返回的值就是缓存区的值,既是在加1之前需要先备份,这里的备份地址就是[ebp-0E8h]=2,之后i=i+1=3,返回的值为缓存区[ebp-0E8h]=2,第二次入栈的就是第二个表达式的返回值[ebp-0E8h]=2,而第一次入栈的是第一个表达式的返回值i的值(此时已经改为3),故输出栈里面是【3,2】,打印输出 2,3.

下面的几个例子是具有两个变量的,道理是类似的,要注意,具有后置++/--的,返回的都是缓存区的值,前置的都是返回变量本身的值,另外本身的值可能受另一个表达式的影响,所以,在没有计算完之前,是不知道i的值的。

1、

 int x=2,y=3;printf("%d,%d\n",(x++)+y,++y);//等价x+++y

第一个入栈的是y值本身,而其他表达式对其无影响,故入栈y==4

第二个入栈的是表达式的缓存区的值,为x+y=2+4=6,故入栈 6

输出值为6 4

下面的例子可以自己分析试试,看看反汇编就立刻明白含义了,就不一一说明了

2、

 int x=2,y=3;printf("%d,%d\n",x+y++,++y);

3、

 int x=2,y=3;printf("%d,%d\n",x+y,++y);

4、

 int x=2,y=3;printf("%d,%d\n",x+y,y++);

关于printf(%d,%d,i--,i++)的问题相关推荐

  1. 关于C语言中printf函数“输出歧视”的问题

    目录 关于C语言中printf函数"输出歧视"的问题 问题描述 探索问题原因 另一种研究方法 问题结论 关于C语言中printf函数"输出歧视"的问题 问题描述 ...

  2. Go 学习笔记(46)— Go 标准库之 fmt(输入/输出格式化参数、Printf/Fprintf/Sprintf区别、Println/Fprintln/Sprintln 区别)

    1. 概述 import "fmt" fmt 包实现了类似 C 语言 printf 和 scanf 的格式化 I/O .格式化动作( verb )源自 C 语言但更简单. 2. P ...

  3. c语言字符串 s,c – printf格式字符串中“% – *.* s”的含义是什么

    你可以在这里阅读printf的手册页: http://pubs.opengroup.org/onlinepubs/009695399/functions/fprintf.html.但是它更像是法律文本 ...

  4. printf格式化输出几点注记

    搞了很多年c/c++,有很多细小的东西,曾经不止一次遇到,可是一直都是放在零散的地方,要用的时候怎么也找不到,今天,我痛下决心,改掉不良习惯,把这些经验或是tips记录在这里,便于日后查找. 1.在统 ...

  5. PHP函数printf()、sprintf()的用法

    printf()函数优点在于可以格式化输出 格式: %['padding_character][-][width][.precision]type 所有的转换说明都是以%开始,如果想打印一个%符号,必 ...

  6. printf(%d, -10u); 这个输出什么呀, 0或1?

    printf("%d", -1<0u); 这个输出什么呀, 0或1? 周银辉 既然我这么问了, 那么答案自然不是1,而是0 看看下面的代码: 对于-1+0u输出为-1,似乎理 ...

  7. fprintf、printf、sprintf、fscanf、scanf、sscanf 格式化输入输出

    格式化输入输出 1.         fprintf(格式化输出数据至文件) 相关函数  printf,fscanf,vfprintf 表头文件  #include<stdio.h> 定义 ...

  8. 【C】printf warning: unknown conversion type character ‘l‘ in format [-Wformat=]

    1.问题描述 在使用printf.fprintf打印long long类型时报错 printf warning: unknown conversion type character 'l' in fo ...

  9. 【linux】printf在终端打印彩色hello world

    代码 #include <stdio.h>#define NONE "\033[m" #define RED "\033[0;32;31m" #de ...

  10. c语言自定义char*函数返回值是乱码_[每日C语言」printf()函数的修饰符和返回值...

    在上一个小demo<printf()函数(1)>中主要说了一下printf()函数的转换说明符,这些转移说明符是可以被修饰的.我们可以在%d和定义的转义字符之间通过插入修饰符对基本的转换说 ...

最新文章

  1. gvim配置及相关插件安装(过程详细,附图)
  2. Android:你不知道的 WebView 使用漏洞
  3. html时钟翻牌效果,干货满满!如何优雅简洁地实现时钟翻牌器(支持JS/Vue/React)
  4. (案例)使用Cookie保存用户最后一次访问的时间
  5. P2P技术详解(三):P2P中的NAT穿越(打洞)方案详解(进阶分析篇)
  6. php长轮询阻塞,ajax长轮询时php被阻塞
  7. mysql3.5.2 下载_mybatis 3.5.2 jar 下载
  8. arcore 示例_Android增强现实– Android ARCore示例
  9. CC***原理及防范方法
  10. 2019年2月已到,Java 8要收费了吗?
  11. uint8_t / uint16_t / uint32_t /uint64_t 这些数据类型是什么?
  12. 如何在透视表中同时显示客户编码和客户名称
  13. 微信web中IOS系统手机摇一摇功能实现及问题解决
  14. 酒店标识的要求不同其设计也不同
  15. APP元素定位工具Weditor连接夜神模拟器
  16. Android 使用加速度计
  17. java邮箱465端口发送验证码,htmlmail465,465端口发邮件
  18. OpenCore电池显示正在充电:1% 建议维修
  19. Docker入门(基础篇+高级篇)
  20. (转)反汇编算法介绍和应用——线性扫描算法分析

热门文章

  1. 大学生就业的三方协议基本概述
  2. mysql-DTL语言
  3. rto净化效率计算公式_设备综合效率计算公式详解
  4. android 手机存储大小设置,如何让手机内存变大?内存不足解决方法【详解】
  5. 计算机系统集成工作总结,系统集成工作总结报告.docx
  6. 怎么给图片加水印?四个操作步骤
  7. 大数据调度平台Airflow版本升级方案文档(1.X升级到2.X)
  8. 如何在TOMCAT上安装Liferay
  9. python新闻文本爬虫_python学习_新闻联播文字版爬虫(V 1.0版)
  10. 主要计算机网络设备及其主要用途