读书人

青牛群笔试

发布时间: 2012-11-07 09:56:10 作者: rapoo

青牛笔试

这段时间师兄都忙着找工作,一场接一场,有时候一天赶好几个场子,时间来不及就经常让我去帮他们笔试一下,我也借此锻炼一下,看看笔试题的难度,昨天接师兄通知,去青牛笔试,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两次加加操作,再相乘;现在明白了吧?


读书人网 >编程

热点推荐