一个简单的c程序
- #include <stdio.h>
- int main(){
- int m = 10000;
- m = m++;
- printf("%d",m);
- return 0;
- }
然后编译运行,看看发生了什么
- .\m++.exe
- 10000
为什么还是10000?到底发生了什么?
1 先看看我们编译后得到的exe文件。你写的c是无法运行在cpu上的,需要先编译成exe(windows下的可执行文件格式叫Portable Executable(PE)/可移植可执行的意思)。这是一种特殊格式的二进制文件,看起来是这样的
看起来一头雾水完全看不懂吧,看不懂就对了,正常人类看不懂才正常,因为它是给cpu看的
题外话,使用gcc(如果你是使用的gcc)编译时附加m项,例
- gcc -m32 .\m++.c -o m++x32.exe
- gcc -m64 .\m++.c -o m++x64.exe
你会得到两份不同的exe.都可以在x86_64cpu架构的windows上运行,但一般现在的cpu和系统都是64位的。我们接着往下看m++x64.exe.
当然这需要借助一些工具,比如最知名的应该是ida了,如果懂一点汇编就更好了,不懂也没关系。猜也能猜出来cpu看到的是个啥,然后它会怎么样工作,为什么答案是10000.
图中的最左边叫偏移量就是代码在文件中的位置,中间那些十六进制的数就是字节码,cpu能懂的东西,右边是汇编代码,人能看懂的东西,最后分号类是给你阅读的注释,表示程序运行中真实做的事。
其中最关键的信息是 eax,也就是代码中的int m;的确先加了1,然后赋值给了eax,等于10001,然后又被覆盖了,成了10000,所以你打印出来,还是10000
继续看一下m=++m会发生什么?
- #include <stdio.h>
- int main(){
- int m = 10000;
- m = ++m;
- printf("%d",m);
- return 0;
- }
编译后查看汇编代码
如果认真读完这些,应该能理解为什么m=m++值不变,m=++m会加1了,但我个人的建议是永远不要写这样的代码,了解原理后更不应该写容易在人类阅读上有歧义的代码。代码是给机器运行的,但更重要的是给人读的。