1 #include2 int main() 3 { 4 int a=1,a1=1; 5 int b=1,b1=1; 6 printf("(1)后自加:\n"); 7 printf("a+=(a++):\n");// 8 printf("%d\t%d\t%d\n",a,a+=(a++),a); 9 printf("%d\n",a);10 printf("a1+(a1++):\n");//11 printf("%d\t%d\t%d\n",a1,a1+(a1++),a1);12 printf("%d\n",a1);13 14 printf("\n(2)前自加:\n");15 printf("b+=(++b):\n");//16 printf("%d\t%d\t%d\n",b,b+=(++b),b);17 printf("%d\n",b);18 printf("b1+(++b1):\n");//19 printf("%d\t%d\t%d\n",b1,b1+(++b1),b1);20 printf("%d\n",b1);21 return 0;22 }
总的来说挺纠结的,实际上面的结果计算涉及到如下几点:
(1) 当printf()参数表中有自加表达式时执行顺序:
后自加:以 8: printf("%d\t%d\t%d\n",a,a+=(a++),a);在VC6.0中的反汇编结果(见文末)为例:1)倒数第一个参数入栈 (这里值得注意的是入栈时数据占的字节数依据是参数表中该变量的数据类型,且float类型按照double类型的字节数)
2)倒数第二个参数入栈:取(a++)的值得① --> 计算①+a得② --> 把②赋值给a
3)倒数第三个参数入栈
4)控制字符串入栈
5)输出 (这里值得注意的是输出时从栈中取数据时按照格式说明符对应的字节数,且%f对应double类型的字节数)
6)变量a自加1,并更新
前自加:以16: printf("%d\t%d\t%d\n",b,b+=(++b),b);在VC6.0中的反汇编结果(见文末)为例:
1)倒数第一个参数入栈
2)倒数第二个参数入栈:变量b自加1,并更新-->取b的值得① --> 计算b+①得② --> 把②赋值给b
3)倒数第三个参数入栈
4)控制字符串入栈
5)输出
(2)加法运算符'+'的计算顺序
这个也不用怀疑,计算顺序一定是先计算左操作数对应的表达式。
另外,要区分“计算”和“取值”的区别,如果左操作数只是一个变量,而右操作数是表达式。则先计算右操作数表达式的值,然后从左操作数的变量中取值再与该表达式相加。
因此: a+(++a)是 (变量a自加后数值+变量a自加后数值)而不是 (变量当前数值+变量a自加后数值)
以下是部分语句在VC6.0中反汇编结果:
1 8: printf("%d\t%d\t%d\n",a,a+=(a++),a); 2 0040D75E mov eax,dword ptr [ebp-4] 3 0040D761 push eax 4 0040D762 mov ecx,dword ptr [ebp-4] 5 0040D765 add ecx,dword ptr [ebp-4] 6 0040D768 mov dword ptr [ebp-4],ecx 7 0040D76B mov edx,dword ptr [ebp-4] 8 0040D76E mov dword ptr [ebp-14h],edx 9 0040D771 mov eax,dword ptr [ebp-14h] 10 0040D774 push eax 11 0040D775 mov ecx,dword ptr [ebp-4] 12 0040D778 push ecx 13 0040D779 push offset string "%d\t%d\t%d\n" (00422fdc) 14 0040D77E mov edx,dword ptr [ebp-4] 15 0040D781 add edx,1 16 0040D784 mov dword ptr [ebp-4],edx 17 0040D787 call printf (00401080) 18 0040D78C add esp,10h 19 9: printf("%d\n",a); 20 0040D78F mov eax,dword ptr [ebp-4] 21 0040D792 push eax 22 0040D793 push offset string "%c\n" (0042201c) 23 0040D798 call printf (00401080) 24 0040D79D add esp,8 25 10: printf("a1+(a1++):\n");// 26 0040D7A0 push offset string "a1+(a1++):\n" (00422fd0) 27 0040D7A5 call printf (00401080) 28 0040D7AA add esp,4 29 11: printf("%d\t%d\t%d\n",a1,a1+(a1++),a1); 30 0040D7AD mov ecx,dword ptr [ebp-8] 31 0040D7B0 push ecx 32 0040D7B1 mov edx,dword ptr [ebp-8] 33 0040D7B4 add edx,dword ptr [ebp-8] 34 0040D7B7 mov dword ptr [ebp-18h],edx 35 0040D7BA mov eax,dword ptr [ebp-18h] 36 0040D7BD push eax 37 0040D7BE mov ecx,dword ptr [ebp-8] 38 0040D7C1 push ecx 39 0040D7C2 push offset string "%d\t%d\t%d\n" (00422fdc) 40 0040D7C7 mov edx,dword ptr [ebp-8] 41 0040D7CA add edx,1 42 0040D7CD mov dword ptr [ebp-8],edx 43 0040D7D0 call printf (00401080) 44 0040D7D5 add esp,10h 45 12: printf("%d\n",a1); 46 0040D7D8 mov eax,dword ptr [ebp-8] 47 0040D7DB push eax 48 0040D7DC push offset string "%c\n" (0042201c) 49 0040D7E1 call printf (00401080) 50 0040D7E6 add esp,8 51 13: 52 14: printf("\n(2)前自加:\n"); 53 0040D7E9 push offset string "%d\t%d\n" (00422fc0) 54 0040D7EE call printf (00401080) 55 0040D7F3 add esp,4 56 15: printf("b+=(++b):\n");// 57 0040D7F6 push offset string "b+=(++b):\n" (00422fa8) 58 0040D7FB call printf (00401080) 59 0040D800 add esp,4 60 16: printf("%d\t%d\t%d\n",b,b+=(++b),b); 61 0040D803 mov ecx,dword ptr [ebp-0Ch] 62 0040D806 push ecx 63 0040D807 mov edx,dword ptr [ebp-0Ch] 64 0040D80A add edx,1 65 0040D80D mov dword ptr [ebp-0Ch],edx 66 0040D810 mov eax,dword ptr [ebp-0Ch] 67 0040D813 add eax,dword ptr [ebp-0Ch] 68 0040D816 mov dword ptr [ebp-0Ch],eax 69 0040D819 mov ecx,dword ptr [ebp-0Ch] 70 0040D81C push ecx 71 0040D81D mov edx,dword ptr [ebp-0Ch] 72 0040D820 push edx 73 0040D821 push offset string "%d\t%d\t%d\n" (00422fdc) 74 0040D826 call printf (00401080) 75 0040D82B add esp,10h 76 17: printf("%d\n",b); 77 0040D82E mov eax,dword ptr [ebp-0Ch] 78 0040D831 push eax 79 0040D832 push offset string "%c\n" (0042201c) 80 0040D837 call printf (00401080) 81 0040D83C add esp,8 82 18: printf("b1+(++b1):\n");// 83 0040D83F push offset string "b1+(++b1):\n" (00422fb4) 84 0040D844 call printf (00401080) 85 0040D849 add esp,4 86 19: printf("%d\t%d\t%d\n",b1,b1+(++b1),b1); 87 0040D84C mov ecx,dword ptr [ebp-10h] 88 0040D84F push ecx 89 0040D850 mov edx,dword ptr [ebp-10h] 90 0040D853 add edx,1 91 0040D856 mov dword ptr [ebp-10h],edx 92 0040D859 mov eax,dword ptr [ebp-10h] 93 0040D85C add eax,dword ptr [ebp-10h] 94 0040D85F push eax 95 0040D860 mov ecx,dword ptr [ebp-10h] 96 0040D863 push ecx 97 0040D864 push offset string "%d\t%d\t%d\n" (00422fdc) 98 0040D869 call printf (00401080) 99 0040D86E add esp,10h100 20: printf("%d\n",b1);101 0040D871 mov edx,dword ptr [ebp-10h]102 0040D874 push edx103 0040D875 push offset string "%c\n" (0042201c)104 0040D87A call printf (00401080)105 0040D87F add esp,8106 21: return 0;107 0040D882 xor eax,eax108 22: }