解决C语言自加的问题:(a++)*(++a)*(a++)*(++a);
来源:互联网 发布:手机审批软件 编辑:程序博客网 时间:2024/04/28 23:19
void main(){ int a=5; int b; b = (a++)*(a++); printf("%d\n",b);}
面试时的这个题目:这无疑就是在考察自加的问题,类似的问题还有许多:
(a++)*(a++)*(++a);(a++)*(++a)*(a++);(a++)*(++a)*(a++)*(++a);(a++)*(a++)+(++a)*(a++);(a++)*(++a)+(a++)+(a++);
像这样一连串的写法,无疑给我们分析这个表达式造成了很大的困难。
要搞清楚这个问题唯一就是看编译后的汇编代码,看看到底是如何编译的?
我经过总结,编译过程是这样的(具体的编译原理我不是很清楚),这样的表达式先表示成语法树,假设是这个表达式(a++)*(++a)*(a++)*(++a);其语法树的,求解过程是:
1.先计算(a++)*(++a)得出的结果放入寄存器eax
2.再计算 eax*(a++) 得出的结果还是放入寄存器eax
3.最后计算eax*(++a) 得出表达式的结果
在计算每一步的时候,如果二元表达式左边或右边有++a,则先计算++a的值并放入a变量,然后将两个a的值相乘。
第一步的计算就是,++a; eax = a*a ;
第二步的计算就是,eax = eax*a;
第三步的计算就是,++a; eax = eax * a;
最后得出的值就是表达式的值,再最后再补充未计算的a++表达式。
这个表达式的VC6.0的汇编代码如下:
; 7 : b = (a++)*(++a)*(a++)*(++a); 000268b 45 fc mov eax, DWORD PTR _a$[ebp] 0002983 c0 01 add eax, 1 0002c89 45 fc mov DWORD PTR _a$[ebp], eax 0002f8b 4d fc mov ecx, DWORD PTR _a$[ebp] 000320f af 4d fc imul ecx, DWORD PTR _a$[ebp] 000360f af 4d fc imul ecx, DWORD PTR _a$[ebp] 0003a8b 55 fc mov edx, DWORD PTR _a$[ebp] 0003d83 c2 01 add edx, 1 0004089 55 fc mov DWORD PTR _a$[ebp], edx 000430f af 4d fc imul ecx, DWORD PTR _a$[ebp] 0004789 4d f8 mov DWORD PTR _b$[ebp], ecx 0004a8b 45 fc mov eax, DWORD PTR _a$[ebp] 0004d83 c0 01 add eax, 1 0005089 45 fc mov DWORD PTR _a$[ebp], eax 000538b 4d fc mov ecx, DWORD PTR _a$[ebp] 0005683 c1 01 add ecx, 1 0005989 4d fc mov DWORD PTR _a$[ebp], ecx
分析这样的表达式必须要非常清楚运算符的优先级,依据不同的优先级,来分析每个子表达式的值,逐步的分析出表达式的值。
再来一个表达式:
; 7 : b = (a++)*(++a)+(a++)+(++a); 000268b 45 fc mov eax, DWORD PTR _a$[ebp] 0002983 c0 01 add eax, 1 0002c89 45 fc mov DWORD PTR _a$[ebp], eax 0002f8b 4d fc mov ecx, DWORD PTR _a$[ebp] 000320f af 4d fc imul ecx, DWORD PTR _a$[ebp] 0003603 4d fc add ecx, DWORD PTR _a$[ebp] 000398b 55 fc mov edx, DWORD PTR _a$[ebp] 0003c83 c2 01 add edx, 1 0003f89 55 fc mov DWORD PTR _a$[ebp], edx 0004203 4d fc add ecx, DWORD PTR _a$[ebp] 0004589 4d f8 mov DWORD PTR _b$[ebp], ecx 000488b 45 fc mov eax, DWORD PTR _a$[ebp] 0004b83 c0 01 add eax, 1 0004e89 45 fc mov DWORD PTR _a$[ebp], eax 000518b 4d fc mov ecx, DWORD PTR _a$[ebp] 0005483 c1 01 add ecx, 1 0005789 4d fc mov DWORD PTR _a$[ebp], ecx
- 解决C语言自加的问题:(a++)*(++a)*(a++)*(++a);
- 关于c语言自加运算的问题(a++)
- 关于C语言中a++和++a的问题
- C语言-数组a[]:a与&a的不同
- 如何解决 a+b >c 和 a*b 和 a-b 的 integer overflow 问题
- 剖析C语言中a=a+++++a的无聊问题
- 剖析C语言中a=a+++++a的无聊问题
- 关于C语言中的a++,++a,a--,--a;
- C语言的A*算法
- [C] (++a)*(a++)+(++a)的值是多少?
- 关于C语言中a=a++与a=++a的研究
- 关于C语言的printf("%d,%d,%d,%d\n",a,++a,a--,a--);
- C语言拾遗:(int)a、&a、(int)&a、(int&)a的区别
- C语言数组的一些运算*a,a+1,&a+1,a+0
- 关于自增运算符++a和a++的问题
- [c/c++]A a();与A a;
- a++和++a的问题
- C语言 int &a
- oracle数据库迁移
- spring事务配置Caused by: java.lang.ClassNotFoundException: org.hibernate.engine.SessionFactoryImplemento
- SEOer:思路决定出路 细节决定成败
- psql 常用命令
- Android开发者应该深入学习的10个项目
- 解决C语言自加的问题:(a++)*(++a)*(a++)*(++a);
- document.getElementById("xx").style.xxx中的所有属性是什么
- hdu 2191
- UVA 11825 Hackers' Crackdown
- log4j 配置实例
- Java 中Enum 的扩展
- MyBaits_动态SQL
- 22-函数细节问题
- 深入浅出多网卡绑定技术