首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > 编程 >

青牛群笔试

2012-11-07 
青牛笔试这段时间师兄都忙着找工作,一场接一场,有时候一天赶好几个场子,时间来不及就经常让我去帮他们笔试

青牛笔试

                          这段时间师兄都忙着找工作,一场接一场,有时候一天赶好几个场子,时间来不及就经常让我去帮他们笔试一下,我也借此锻炼一下,看看笔试题的难度,昨天接师兄通知,去青牛笔试,C/C++方向,技术试题中有一道题我想在这里说下,原题大致如下:

#include<stdio.h>
#define pt(x) (x*x)
int main()
{
int i=3;
int j=0,k=0;
j= pt(i++);
k= pt(++i);
printf("j= %d,k= %d\n",j,k);
}


问:输出的结果是什么?


答案是:j=9,k=49    

第一个答案j=9还好理解,k=49 完全想不通,遇到这种题,就算知道正确答案,但是想又想不通为什么就让人郁闷了,而且很多人会说编译器不同结果也不一样,我是用GCC 来跑一遍得出的结果:j=9,k=49  。

那么如何理解,对于这种题,建议大家出查源码的汇编代码,就会很清楚计算机是如何得到这个结果的,我们贴下起汇编代码,如下:

相对应的汇编代码:

#include<stdio.h>

#define pt(x) (x*x)

int main()

{

00CA1380  push       ebp 

00CA1381  mov        ebp,esp 

00CA1383  sub        esp,0E4h 

00CA1389  push       ebx 

00CA138A  push       esi 

00CA138B  push       edi 

00CA138C  lea        edi,[ebp-0E4h] 

00CA1392  mov        ecx,39h 

00CA1397  mov        eax,0CCCCCCCCh 

00CA139C  rep stos   dword ptr es:[edi] 

         int i=3;

00CA139E  mov        dword ptr [i],3  //把 3赋值给 i

         int j=0,k=0;

00CA13A5  mov        dword ptr [j],0  //初始化 j,k变量为 0

00CA13AC  mov        dword ptr [k],0 

         j= pt(i++);

00CA13B3  mov        eax,dword ptr [i] //先把 i的值取出到寄存器 eax中

00CA13B6  imul       eax,dword ptr [i]  //把i的值取出与原寄存器值相乘,结果保存在寄存器中

00CA13BA  mov        dword ptr [j],eax  //把寄存器的值 9赋值给 j

00CA13BD  mov         ecx,dword ptr [i]  //最后把 i取出到寄存器中,加一

00CA13C0  add         ecx,1 

00CA13C3  mov         dword ptr [i],ecx  //再赋值给 i ,此时 i 为 4

00CA13C6  mov         edx,dword ptr [i]  //同理与上,再对 i取出加一重新赋值给 i

00CA13C9  add         edx,1 

00CA13CC  mov         dword ptr [i],edx  //此时 i为 5

         printf("i= %d\n",i);

00CA13CF  mov        esi,esp 

00CA13D1  mov        eax,dword ptr [i] 

00CA13D4  push       eax 

00CA13D5  push       offset string "i= %d\n" (0CA574Ch) 

00CA13DA  call       dword ptr [__imp__printf (0CA82B0h)] 

00CA13E0  add        esp,8 

00CA13E3  cmp        esi,esp 

00CA13E5  call       @ILT+295(__RTC_CheckEsp) (0CA112Ch) 

         k= pt(++i);

00CA13EA  mov         eax,dword ptr [i]  //首先将 i取出到寄存器 eax

00CA13ED  add         eax,1 //加一

00CA13F0  mov         dword ptr [i],eax  //将寄存器 eax的值赋值给变量 i,此时 i 的值为6

00CA13F3  mov         ecx,dword ptr [i] 

00CA13F6  add         ecx,1 

00CA13F9  mov         dword ptr [i],ecx  //同理,此时 i的值为7

00CA13FC  mov         edx,dword ptr [i]  //将 i 值取出到寄存器

00CA13FF  imul        edx,dword ptr [i]  //再将 i 值与寄存器值相乘,eax为 49

00CA1403  mov         dword ptr [k],edx  //将 eax的值赋值给 K

         printf("j= %d,k= %d\n",j,k);

00CA1406  mov        esi,esp 

00CA1408  mov        eax,dword ptr [k] 

00CA140B  push       eax 

00CA140C  mov        ecx,dword ptr [j] 

00CA140F  push       ecx 

00CA1410  push       offset string "j= %d,k= %d\n" (0CA573Ch) 

00CA1415  call       dword ptr [__imp__printf (0CA82B0h)] 

00CA141B  add        esp,0Ch 

00CA141E  cmp        esi,esp 

00CA1420  call       @ILT+295(__RTC_CheckEsp) (0CA112Ch)  

}

结论:GCC 编译器在处理表达式: i++*i++ 时,先取 i 的值,进行运算,再对 i 两次加加操作,而对表达式:++i *++i 时,先对 i两次加加操作,再相乘;现在明白了吧?


热点排行