printf小结
下午健身前和lxt兄弟讨论了一个关于 printf 输出的问题,恰巧以前见过类似的,回来写一个收获总结。
首先看一个这样一个例子
#include<cstdio>
int i;
int main()
{
printf("%d %d", i, i ++);
}
Output:
1 0

其实是这样的,printf参数的顺序是一个未定义行为,编译器不同,实现不同,gcc和clang是右到左,msvc是左到右,所以实现这种未定义行为不要引入有变化的参数
就拿我的gcc来解释一下
printf("%d %d", i, i ++);
这句话有两个表达式 i 和 i ++,我们将 i 视为第一个表达式,将 i ++ 视为第二个表达式。
打印标量表达式的顺序是从左到右,但是变量表达式的评估顺序是从右到左,即先去计算位于最右侧的第二个表达式,然后是最左侧表达式。
我们知道 i ++ 是 i 的后增量运算符。
在第一步中(右侧首先赋值再加加),那么 i 的值保持为0(不增加其值),并且在下一步中(左侧表达式),i 的值增加到1。因此,第二个表达式(i ++)值为0并且第一个表达式 i 值递增获得的值为 1。
如前所述,打印值的顺序是从左到右。因此,首先打印第一个表达值,然后打印下一个。因此,输出序列为1 0。

好吧,让计算机汇编语言来数据公道话,
在实际的汇编语言中这段代码深层含义其实是
1.把 i 的值存入缓冲器[..a.] = 0;
2.i 值加1,i 值为1;
3.把1如缓冲器[..b.] = 1;
4,把缓冲器[..a.] = 0,入栈;
5.把缓冲器[..b..]=1,入栈;
栈(后进先出),打印顺序1, 0
好了接下来应该懂了为什么
printf("%d %d\n", i, i++);
会是1,0了
不过还有一个问题
#include<cstdio>
int i;//全局默认是0 int main()
{
printf("%d\n", ++i);
printf("%d\n", i);
i = ;
printf("%d %d\n", ++i, i); }
结果是
1
1
1,0
而如果在局部里声明
结果是
1
1
1,1
猜测是全局和局部的事,不会QAQ~,后续更新
参考博客(文章):https://blog.csdn.net/qq_33266987/article/details/51965221
https://blog.csdn.net/u014644714/article/details/77688321/?tdsourcetag=s_pctim_aiomsg
https://www.quora.com/int-i-0-printf-d-d-i-i++-what-is-the-output-of-this-statement
https://blog.csdn.net/yangquanhui1991/article/details/51786380
感谢上述前辈的博客!
学艺不精,有任何不足或者错误请大神多多指教
工具:
http://tool.chinaz.com/Tools/textencrypt.aspx
加密文字:
U2FsdGVkX1/nj0dlo2LGp8dtHyMkOBjFux9QbhsmqhBtyC5sgxZZOL0MXIIocHZb
hUhU+c3CrJ8m9Zg+o+6vGiVwH8cjFITRkANC97IJZAJWUKSaYIPrOfxXyyXswNAS
uTcq0j/Bi8VwoWr7/UsBxh1QIaL0EdRhonptmqlBn1lDkbQnrrZnu1Efxn7jS+yh
wdjZSgtAme33No3KUAaM1l6z3acRm52/kIPW3BNsgVaHUFUAGFlnzxE4dN2J2Xkr
密钥:
139*****136
printf小结的更多相关文章
- linux printf和fork()问题小结
总结如下: printf("father begin"); pid_t pid; pid = fork(); ) { ) { printf("father out&quo ...
- C语言 指针小结
指针 -->指针变量 类型名 *变量名 int *point1; char *point2; 注意:*p可以直接使用,它代表指针p指向的变量,*p可以当做被指向的变量使用!~~~~ 一个变量的地 ...
- Linux环境下段错误的产生原因及调试方法小结(转)
最近在Linux环境下做C语言项目,由于是在一个原有项目基础之上进行二次开发,而且 项目工程庞大复杂,出现了不少问题,其中遇到最多.花费时间最长的问题就是著名的“段错误”(Segmentation F ...
- Java中文编码小结
Java中文编码小结 1. 只有 字符到字节 或者 字节到字符 的转换才存在编码转码; 2. Java String 采用 UTF-16 编码方式存储所有字符.unicode体系采用唯一的码点表示唯一 ...
- Linux环境下段错误的产生原因及调试方法小结
转载自http://www.cnblogs.com/panfeng412/archive/2011/11/06/2237857.html 最近在Linux环境下做C语言项目,由于是在一个原有项目基础之 ...
- 函数fgets和fputs、fread和fwrite、fscanf和fprintf用法小结 (转)
函数fgets和fputs.fread和fwrite.fscanf和fprintf用法小结 字符串读写函数fgets和fputs 一.读字符串函数fgets函数的功能是从指定的文件中读一个字符串到字符 ...
- objective-c基础教程——学习小结
objective-c基础教程——学习小结 提纲: 简介 与C语言相比要注意的地方 objective-c高级特性 开发工具介绍(cocoa 工具包的功能,框架,源文件组织:XCode使用介绍) ...
- [数据结构]RMQ问题小结
RMQ问题小结 by Wine93 2014.1.14 1.算法简介 RMQ问题可分成以下2种 (1)静态RMQ:ST算法 一旦给定序列确定后就不在更新,只查询区间最大(小)值!这类问题可以用倍增 ...
- [数据结构]KMP小结
KMP小结 By Wine93 2013.9 1.学习链接: http://www.matrix67.com/blog/archives/115 2.个人小结 1.KMP在字符串中匹配中起着巨大作 ...
随机推荐
- 详解 Map集合
(请关注 本人"集合总集篇"博文--<详解 集合框架>) 首先,本人来讲解下 Map集合 的特点: Map集合 的特点: 特点: 通过 键 映射到 值的对象 一个 映射 ...
- Springboot:员工管理之查询员工列表(十(6))
构建员工controller com\springboot\controller\EmployeeController.java package com.springboot.controller; ...
- windows 系统使用技巧
1 自定义发送到C:\Users\adm\AppData\Roaming\Microsoft\Windows\SendTo 2 自定义关机shutdown -s -t time,可写在快捷方式中shu ...
- Java 多线程 -- 指令重排(HappenBefore)
指令重排是指:代码执行顺序和预期不一致. 代码运行一般步骤为: 1.从内存中获取指令解码 2.计算值 3.执行代码操作 4.把结果写回内存 而写回内存的操作比较耗时,CPU为了性能,可能不会等它完成, ...
- 苹果登录服务端JWT算法验证-PHP
验证参数 可用的验证参数有 userID.authorizationCode.identityToken,需要iOS客户端传过来 验证方式 苹果登录验证可以选择两种验证方式 具体可参考这篇文章 htt ...
- 作业九——DFA最小化,语法分析初步
- 基于jenkins自动打包并部署Tomcat环境
传统网站部署的流程 在运维过程中,网站部署是运维的工作之一.传统的网站部署的流程大致分为:需求分析->原型设计->开发代码->提交代码->内网部署->内网测试->确 ...
- SpringBoot 集成Swagger2自动生成文档和导出成静态文件
目录 1. 简介 2. 集成Swagger2 2.1 导入Swagger库 2.2 配置Swagger基本信息 2.3 使用Swagger注解 2.4 文档效果图 3. 常用注解介绍 4. Swagg ...
- vs code中Vue代码格式化的问题
个人网站 https://iiter.cn 程序员导航站 开业啦,欢迎各位观众姥爷赏脸参观,如有意见或建议希望能够不吝赐教! VSCode自从更新之后,vue文件的html代码格式化就失效了,而且vu ...
- Eclipse中获取html jsp 标签的属性提示信息方法
操作方法: windows------preferences----------搜索 html----------找到 html Source这项---------找到 content assist ...