1. 程式人生 > >關於i++和++i以及左值,右值

關於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)型別,寫++變數和變數++編譯器都經過優化,採用++變數的方式.但是對於自定義類物件如果過載先++,和後++操作符那麼要使用先++,因為這時編譯器,不可能對你的型別進行優化!