Fork me on GitHub

printf小结

 

下午健身前和lxt兄弟讨论了一个关于 printf 输出的问题,恰巧以前见过类似的,回来写一个收获总结。

首先看一个这样一个例子

1 #include<cstdio>
2 int i;
3 int main()
4 {
5     printf("%d %d", i, i ++);
6 }

Output:

1 0

其实是这样的,printf参数的顺序是一个未定义行为,编译器不同,实现不同,gcc和clang是右到左,msvc是左到右,所以实现这种未定义行为不要引入有变化的参数

就拿我的gcc来解释一下

1  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了

 

不过还有一个问题

 1 #include<cstdio>
 2 int i;//全局默认是0 3 int main()
 4 {
 5     printf("%d\n", ++i);
 6     printf("%d\n", i);
 7     i = 0;
 8     printf("%d %d\n", ++i, i);
 9 
10 }

结果是

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/How-can-this-code-be-explained-Int-k-34-printf-d-d-d-d-n-k-k+9-k-78-k-k++-87-87-87-34

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

posted @ 2019-03-08 19:55  GerJCS  阅读(361)  评论(0编辑  收藏  举报