Rookie2

1st Edition

导航

i++和++i

今天看到一个C语言的面试题:

 1 #include<stdio.h>
 2 
 3 #define PRODUCT(X) (X*X)
 4 
 5 int main()
 6 {
 7     int i = 3,
 8         j, k;
 9     j = PRODUCT(i++);
10     k = PRODUCT(++i);
11 
12     printf("j = %d, k = %d", j, k);
13 }

先说答案吧:

j = 9, k = 49

我本来觉得自己C学的还不错的, 可是上来一算,j = 3 * 4 = 12, k = 6 * 7 = 42. 跟答案差的太远了, 我又算了几下, 百思不得其解, 看来得从汇编查找原因了.先把宏展开来看:

j = i++*i++;
k = ++i*++i;

先看 j = i++*i++; 的汇编代码:

 1 ;语句 j = i++*i++ 的汇编代码
 2 ;
 3 001013F5  mov         eax,dword ptr [i]  ;将i值存入eax,eax=3
 4 001013F8  imul        eax,dword ptr [i]  ;做乘法运算,结果9存入eax
 5 001013FC  mov         dword ptr [j],eax  ;eax赋值给j,j=9
 6 ;上面语句已完成j的赋值运算,下面是对i自加运算的处理
 7 001013FF  mov         ecx,dword ptr [i]  ;i的值存入ecx,ecx=3
 8 00101402  add         ecx,1  ;加法运算,3+1=4,存入ecx
 9 00101405  mov         dword ptr [i],ecx  ;ecx赋值给i,i=4
10 00101408  mov         edx,dword ptr [i]  ;edx=4
11 0010140B  add         edx,1  ;edx=4+1=5
12 0010140E  mov         dword ptr [i],edx  ;i=5

哦, 到现在算是整明白了,处理i++时,是先处理其它运算,当其它运算完整以后,再去处理i的自加, 按照这个逻辑, 求k时,先进行++i运算,两次++i以后,i的值变成7, 然后k=7*7=49.这就和答案一样了,原来是这样,看下求k时的汇编语句吧:

 1 ;    k = ++i*++i;
 2 ;
 3 ;先是自增运算
 4 00101411  mov         eax,dword ptr [i]  
 5 00101414  add         eax,1  
 6 00101417  mov         dword ptr [i],eax  
 7 0010141A  mov         ecx,dword ptr [i]  
 8 0010141D  add         ecx,1  
 9 00101420  mov         dword ptr [i],ecx  
10 ;然后求乘
11 00101423  mov         edx,dword ptr [i]  
12 00101426  imul        edx,dword ptr [i]  
13 0010142A  mov         dword ptr [k],edx  

看了汇编代码, 和想像中的一样, 呵呵, 看来问题得到解决了, 再给自己加个问题, 如果把j和k全换成i, 结果又怎么样呢?

 1 // test.c
 2 
 3 #include<stdio.h>
 4 
 5 int main()
 6 {
 7     int i = 3;
 8     i = i++*i++;
 9     printf("%d\n", i);
10     i = ++i*++i;
11     printf("%d\n", i);
12     getchar();
13 }


当然, 最终的结果是:

11
169

不难理解, i先进行乘法运算, 得到结果9. 再进行两次自增运算, 得到结果11.

后一句运算, i先进行两次自增运算, 得到i=13; 再进行乘法运算, 13 * 13 = 169, 正解.
问题解决.

posted on 2012-11-11 14:19  Rookie2  阅读(924)  评论(0编辑  收藏  举报