起因:有个小伙伴在群里问了这样一个问题:有会 C 语言的吗?
自告(zhuang)奋(bi)勇的说了一句:在!
代码如下:
|
|
大概看了 2 秒,给出了答案:
2,2,3
结果惨遭打脸,一世英名毁于一题。
原因:
首先应该说明的是这段代码在不同的编译环境中结果是不一样的。
in Mac OS 10.13 GCC 4.2.1 (Xcode): 1,2,3
in Compile and Execute C Online (GNU GCC v7.1.1): 2,3,3
得知结果后,在想 What the FXXK 到底为什么,哪里错了。
错误总结:
第一:代码执行顺序
GCC 中 printf 函数的执行顺序是由右到左
的。
直接运算明显错误,导致结果肯定不一致
第二:++i and i++
前自增运算符(++i)先加 1,再使用
后自增运算符(i++)先使用 i,执行语句代码后再加 1
第三:“计算”不等于“输出”
自增运算是要在整条语句结束以后才自加 1 的
答案:
想理解答案首先要理解编译顺序:
在 GCC v7.1.1 的编译器解释为:
从右往左计算:
- i++ 等于 1(整条语句执行完毕之后才会执行 +1 操作)
- i 在这里还是等于 1
- ++i 等于 2
- 执行 i++ 操作 i 等于3
所以结果 2,3,3
是这样得出来的。
在 GCC 4.2.1 中
使用 GCC -o
命令来编译,直接报错 Unsequenced modification and access to 'a'
理解为中文的大概意思就是 在一个表达式中改变了变量的值,又在同一个表达式的另一个地方使用了同一个变量的值,这样是不被允许的
导致直接编译通过不了。
在 Xcode 中
在 Xcode 编译却被通过,只不过结果和上述不一致的(手动笑脸)。
总结
对于这种代码,不同编译器结果会不一样,避免使用才是真正的答案,除人为强行的规范代码,对于这些底层编译原理还要理解和学习。
这篇文章从解决问题、简单理解原理到写出这篇博客,耗时三小时,现在是深夜 3 点钟。
有收获的感觉好爽。