【C】由printf("%d\t%d\t%d\n",a,a+=(a++),a);引起的思考


 1 #include<stdio.h>
 2 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,10h
100 20:       printf("%d\n",b1);
101 0040D871   mov         edx,dword ptr [ebp-10h]
102 0040D874   push        edx
103 0040D875   push        offset string "%c\n" (0042201c)
104 0040D87A   call        printf (00401080)
105 0040D87F   add         esp,8
106 21:       return 0;
107 0040D882   xor         eax,eax
108 22:   }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM