前++和后++引發的血案~~!!


先看一段奇葩代碼:

int main(void)
{
int x = 4;
int y;
y = (x++);
printf("hello world. y = %d.\n", y);
 
x = 4;
y = (x++)+(x++);
printf("hello world. y = %d.\n", y);
 
 x = 4;
y = (x++)+(x++)+(x++);
printf("hello world. y = %d.\n", y);
 
 x = 4;
y = (x++)+(x++)+(x++)+(x++);
printf("hello world. y = %d.\n", y);
 
x = 4;
y = (++x);
printf("hello world. y = %d.\n", y);
 
x = 4;
y = (++x)+(++x);
printf("hello world. y = %d.\n", y);
 
 x = 4;
y = (++x)+(++x)+(++x);
printf("hello world. y = %d.\n", y);
 
 
x = 4;
y = (++x)+(++x)+(++x)+(++x);
printf("hello world. y = %d.\n", y);
return 0;
     
}

 

而在VS2012(windows運行環境)的測試結果為:

\\后++

y = 4.

y = 8.   //4+4

y = 12. //4+4+4

y = 16. //4+4+4+4

\\前++

y = 5.   

y = 12. //6+6

y = 21. //7+7+7

y = 32. //8+8+8+8

 

  

在Ubuntu上測試的結果為:

//后++

y = 4.

y = 9.   //4+5

y =15.  //4+5+6

y = 22. //4+5+6+7

//前++

y = 5.

y = 12. //6+6

y = 19. //6+6+7

y = 27. //6+6+7+8

 

對應windows上的測試結果都比較好理解:

1、對於后++而言,在賦值之前x不會遞增,所以每次多一個x++不過是多一個4的累加而已。

2、對於前++而言,在賦值前x已經遞增,所以每次多一個x所對應內存的值都被提高1,最后再相加。

所以出現了出現了6*2  7*3  8*4的結果。

 

對於linux上的測試結果就不太容易想明白:

1、對於后++而言第二就和windows的結果不一樣了,這是因為linux用了產生中間變量的方式。

如:y = (x++)+(x++);被分成了多步:1)tmp = x;  x = x + 1;2) tmp1 = x;  x = x + 1;  3)y  = tmp + tmp1;

1)中tem等於4,並遞增了x;2)中tmp1就等4了也遞增了x;3)中就等到結果4+5=9

當(x++)遞增到三個時也是一樣分析,只不過會多一個中間變量tmp2.

2、對於前++,第三個和windows的結果不同了,也是產生了中間變量的緣故:

如:y = (++x)+(++x)+(++x); 被分成了多步:

1)tmp = (++x)+(++x);  2)y = tmp  + (++x);

從而y = 6+6+7

再如:y = (++x)+(++x)+(++x); 被分成了多步:

1)tmp = (++x)+(++x);  2)tmp1 = tmp  + (++x);  3)y =  tmp1 + (++x);

從而y = 6+6+7+8

這里可能唯一讓人困惑的是為什么(++x)+(++x)中間沒有產生中間變量?而(x++)+(x++)卻產生了中間變量?

我猜想是因為前++應為是先遞增后賦值,所以直接是x = x+1所以也就沒有中間變量的產生,而作為最前面的

兩個(++x)與‘+’作用產生一個表達式:(++x)+(++x),這個表達式賦值給一個中間變量在與后面的表達式依次作用。

總結:

   1、對於vs的編譯器,在一條語句中,沒有產生多余的中間變量,而ubuntu中因為產生了中間的變量。

所以后++時ubuntu對x的內存空間有更多的操作,而前++時vs對x的內存空間有更多的操作。導致了結果的不一致。

   2、得知了第一點之后,我們應該注意在一條語句中,不要對一個變量進行多次的操作,因為你不知道編譯器,對這條語句將產生多少個中間變量,而引發血案~~


免責聲明!

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



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