關於i++和++i以及左值,右值
原本一直對i++和++i的區別不是很在意,覺得i++就是先用了i的值(用於賦值之類的操作),再i自加1.
而++i就是把i的值先自加1再用作其他操作.
很多人都問類似於j=++i+++i+i;之類的題目,個人覺得除了有些變態的學校的變態的考試會考.其他根本用不到.如果你在實際寫程式碼的時候這樣寫,不但是給自己找麻煩,以後程式碼維護時,你也會被人在心裡詛咒很久的....
貌似跑題了,汗.... 反正以前就一直沒在意這個.
不過今天無意之間看到了帖子上有人說 i++=5; //不合法
++i=5; //合法
覺得有點奇怪,所以就由著自己的興趣找了些資料.說些自己的看法:
一. 這個問題牽涉到得首先是左值(L-value)和右值(R-value)的概念;
1. 我查資料的時候發現很多地方都引用一句話:"通俗的講,左值就是能夠出現在賦值符號左面的東西,而右值就是那些可以出現在賦值符號右面的東西了。"我覺得這句話在剛開始理解的時候是什麼用都沒有的一句廢話.因為我們都不知道哪些東西應該放在賦值符號的左邊,哪些東西又應該放在賦值符號的右邊這樣說是沒有意義的.
2.接著我找到個比較靠譜的定義:左值是指具有對應的可由使用者訪問的儲存單元,並且能由使用者改變其值的量。如一個變數就是一個左值,因為它對應著一個儲存單元,並可由程式設計者通過變數名訪問和改變其值。
(下面的第三點是c++primer中的)
3.變數和文字常量都有儲存區,並且有相關的型別。區別在於變數是可定址的(addressable)對於每一個變數都有兩個值與其相聯:
1).它的資料值,儲存在某個記憶體地址中。有時這個值也被稱為物件的右值(rvalue,讀做are-value).我們也可認為右值的意思是被讀取的值(read value)。 文字常量和變數都可 被用作右值。
2).它的地址值——即儲存資料值的那塊記憶體的地址。它有時被稱為變數的左值(lvalue,讀作ell-value)。我們也可認為左值的意思是位置值location value文字常量不能被用作左值
到這裡,左值和右值的基本概念應該清楚了.而一些牛人追求的更細緻的到C89和C99以及C++標準上面的差異就不在我的思考範圍了:)
二.再講講i++和++i的實現
原來也一直迷惑於i++與++i的返回值的問題,但一直沒弄明白.這次一併查清楚吧.
首先對於i++的實現是:
int temp;
temp = i;
i = i+1;
return temp;
而++i的實現是:
i = i+1;
return i;
所以對於我們提出來的問題已經能得到解決了:
i++=5; 是錯誤的是因為i++返回的是編譯器自動分配的臨時變數temp,而這個temp並不是你程式中定義的可定址變數的引用,也就是說你不能通過地址對它進行操作.(換句話說就是不能作為左值)
++i=5;是正確的就是因為其返回值就是i;
再囉嗦幾句關於i++和++i的效率問題:按上面分析來說,++i的效率是比i++效率高些的.(VC)對於內建(built-in)型別,寫++變數和變數++編譯器都經過優化,採用++變數的方式.但是對於自定義類物件如果過載先++,和後++操作符那麼要使用先++,因為這時編譯器,不可能對你的型別進行優化!