賦值操作符的傳回值
1.
a=1;
cout<<a++;
列印:1
cout<<++a;
列印:2
2.
a=1;
c = ( a *= 2 ) + ( a += 3 );
結果:a=5, c=10
c = ( a += 3 ) + ( a *= 2 );
結果:a=8, c=16
解釋:
()的優先順序大於+和=,所以先做賦值,再做兩者之和
a *= 2 是a變為2(改變a的地址中的值),a+=3,再使a變為5,所以,c=5+5;
同理,第二個c=16;
3.
++a將返回a的地址,而a++也因為是賦值操作符而必須返回一個地址,但很明顯地不能是a的地址了,因此編譯器將編寫代碼以從棧中分配一塊和a同樣大小的記憶體,並將a的值複製到這塊臨時記憶體中,然後返回這塊臨時記憶體的地址。由於這塊臨時記憶體是因為編譯器的需要而分配的,與程式員完全沒有關係,因此程式員是不應該也不能寫這塊臨時記憶體的(因為編譯器負責編譯代碼,如果程式員欲訪問這塊記憶體,編譯器將報錯),但可以讀取它的值,這也是返回地址的主要目的。所以如下的語句沒有問題:
( ++a ) = a += 34;
但( a++ ) = a += 34;就會在編譯時間報錯,因為a++返回的地址所標識的記憶體只能由編譯器負責處理,程式員只能獲得其值而已。
a++的意思是先返回a的值,也就是上面說的臨時記憶體的地址,然後再將變數的值加一。如果同時出現多個a++,那麼每個a++都需要分配一塊臨時記憶體(注意前面c = ( a += 3 ) + ( a *= 2 );的說明),那麼將有點糟糕,而且a++的意思是先返回a的值,那麼到底是什麼時候的a的值呢?在VC中,當運算式中出現尾碼“++”或尾碼“—”時,只分配一塊臨時記憶體,然後所有的尾碼“++”或尾碼“—”都返回這個臨時記憶體的地址,然後在所有的可以計算的其他動作符的值計算完畢後,再將對應變數的值寫入到臨時記憶體中,計算運算式的值,最後將對應變數的值加一或減一。
因此:a = 1; c = ( a++ ) + ( a++ );執行後,c的值為2,而a的值為3。而如下:
a = 1; b = 1; c = ( ++a ) + ( a++ ) + ( b *= a++ ) + ( a *= 2 ) + ( a *= a++ );
執行時,先分配臨時記憶體,然後由於5個“()”,其計算順序是從左向右,
計算++a的值,返回增一後的a的地址,a的值為2
計算a++的值,返回臨時記憶體的地址,a的值仍為2
計算b *= a++中的a++,返回臨時記憶體的地址,a的值仍為2
計算b *= a++中的“*=”,將a的值寫入臨時記憶體,計算得b的值為2,返回b的地址
計算a *= 2的值,返回a的地址,a的值為4
計算a *= a++中的a++,返回臨時記憶體的地址,a的值仍為4
計算a *= a++中的“*=”,將a的值寫入臨時記憶體,返回a的地址,a的值為16
計算剩下的“+”,為了進行計算,將a的值寫入臨時記憶體,得值16 + 16 + 2 + 16 + 16為66,寫入c中
計算三個a++欠下的加一,a最後變為19。
在運算式中運用賦值操作符是不被推崇的。因為其不符合平常的數學運算式的習慣,且計算順序很容易搞混。如果有多個“++”操作符,最好還是將運算式分開,否則很容易導致錯誤的計算順序而計算錯誤。並且導致計算順序混亂的還不止上面的a++就完了