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在字符串中匹配中起着巨大作 ...
随机推荐
- JDBC教程——检视阅读
JDBC教程--检视阅读 参考 JDBC教程--W3Cschool JDBC教程--一点教程,有高级部分 JDBC教程--易百 JDBC入门教程 – 终极指南 略读 三层架构详解,JDBC在数据访问层 ...
- 数值计算方法实验之Lagrange 多项式插值 (Python 代码)
一.实验目的 在已知f(x),x∈[a,b]的表达式,但函数值不便计算,或不知f(x),x∈[a,b]而又需要给出其在[a,b]上的值时,按插值原则f(xi)= yi(i= 0,1…….,n)求出简单 ...
- php的一个有意思的命令:-S
php -S localhost:8188 /web 会启动一个监控IP:PORT 的http服务,算是简易的web服务器吧.基本上,实现了PHP+MySQL就可以建立一个简易测试网站的环境.
- phpcms模块安装
工作中需要用到 phpcms开源框架,借鉴了 http://www.cnblogs.com/benpaodelulu/p/6874201.html这个地址,搞定的 ,非常实用 如果有用到的朋友们可 ...
- DZ的CURD
Discuz二次开发-MySQL插入数据(insert) DB::insert($tableName,$data,$flag); $tableName:表名 $data:插入数据,以字段为键值的关联数 ...
- memcache雪崩
缓存雪崩一般是由某个缓存节点失效,导致其他节点的缓存命中率下降, 缓存中缺失的数据(memcache经典场景,当有一个客户端的服务请求过来的时候,首先去查memcache,memcache里面是否缓存 ...
- QT踩坑记录1-Q_OBJECT编译问题
QT踩坑记录1-Q_OBJECT编译问题 QTC++Bugs 错误输出 Q_OBJECT 宏错误的地方会编译出现这样的错误, 无法找到.... 由于自己不想再看到这个错误, 此处 复制自 参考连接1, ...
- Window+Protobuf使用说明
Window+Protobuf使用说明 C++WindowCmakeProtocbuf 介绍 起因 由于项目中要用到二进制存储数据,之前使用的方式是按照字节数依次将数据写入字节流中, 但是这样做起来做 ...
- Spring Boot JPA 中transaction的使用
文章目录 @Transactional的实现 @Transactional的使用 Transaction的传播级别 REQUIRED SUPPORTS MANDATORY NEVER NOT_SUPP ...
- 《Exchange Server 2010 SP1/SP2管理实践》——第2章 搭建Exchange实验环境2.1 网络环境规划...
本节书摘来自异步社区<Exchange Server 2010 SP1/SP2管理实践>一书中的第2章,第2.1节,作者: 王淑江 更多章节内容可以访问云栖社区"异步社区&quo ...