printf("%d,%d",i++,i++);

同学去辅导本科生上机,碰到了一个问题:

int i = 10;
printf("%d,%d,%d",i++,i++,i);

打印出的结果是11,10,12.
同学表示很不解,发到了朋友圈。我饶有兴致地一看,妈的我也不会。
…然后就顺手研究了一下。

首先明确i++和++i这两个语句的区别,举例如下:

a=i++;(分解:a=i; i=i+1;)

a=++i;(分解:i=i+1;a=i;)

其中i++的汇编语句如下:

011413C5  mov         eax,dword ptr [i]  
011413C8  mov         dword ptr [a],eax //把i送到AX,AX送到a,即a=i 
011413CB  mov         ecx,dword ptr [i]  
011413CE  add         ecx,1  
011413D1  mov         dword ptr [i],ecx //i自增1

然后我们看一下上面printf("%d,%d,%d",i++,i++,i);这个语句的反汇编(F10之后在编辑区右侧右键到反汇编)。

01071A75  mov         eax,dword ptr [i]  
01071A78  mov         dword ptr [ebp-0D0h],eax //[0h]<-i (10)
01071A7E  mov         ecx,dword ptr [i]  
01071A81  add         ecx,1  
01071A84  mov         dword ptr [i],ecx  //i++ (11)
01071A87  mov         edx,dword ptr [i]  
01071A8A  mov         dword ptr [ebp-0D4h],edx  //[4h]<-i (11)
01071A90  mov         eax,dword ptr [i]  
01071A93  add         eax,1  
01071A96  mov         dword ptr [i],eax  //i++ (12)
01071A99  mov         esi,esp  
01071A9B  mov         ecx,dword ptr [i]  
01071A9E  push        ecx  //12压栈
01071A9F  mov         edx,dword ptr [ebp-0D0h]  
01071AA5  push        edx  //10压栈
01071AA6  mov         eax,dword ptr [ebp-0D4h]  
01071AAC  push        eax  //11压栈

OK,真相大白。