天天看點

C++的那些事:表達式與語句

1,應該把函數調用當作是一種運算符,這種運算符對參與運算的對象沒有數量限制。

2,關于“左值(lvalue)”和“右值(rvalue)”可以做一個簡單的歸納:當一個對象被用作右值的時候,用的是對象的值(内容);當對象被用作左值的時候,用的是對象的身份(在記憶體中的位置)。

更具體的左值與右值的舉例:c++ priemr 5ed p121

3,運算符的優先級規定了運算對象的組合方式,但是沒有說明運算對象按照什麼順序求值,在大多數的情況下,不會明确求值的順序,比如對于下面的表達式:

先調用f1還是先調用f2是未知的。是以,對于這種運算符來說避免多個運算對象共同修改同一個變量,如下面的代碼中,最終輸出是未能确定的:

但c++中有4種運算符是明确規定了運算對象的求值順序的:邏輯與“&&”、邏輯或"||"、條件(?:)運算符、逗号運算符","。這也是為什麼在我們自己定義的類類型中,一般不會去重載這幾種操作符。

4,短路求值:邏輯與運算符和邏輯或運算符都是先求左側運算對象的值再求右側運算對象的值,當且僅當左側運算對象無法确定表達式的結果時才會計算右側運算對象的值。

5,差別i++與++i

後置操作符需要先儲存原來的值,再将i+1,然後傳回原來的值的副本;而前置操作符,隻需要在原來值上加1,然後傳回。是以++i比i++效率更高,當然如果i為int類型或指針時,編譯器會對i++進行優化,但如果是其他類類型或複雜類的疊代器時就不會了。

6,注意解除引用操作符與++操作符的優先級,在實際代碼中為了簡潔經常将*(i++)寫為*i++。因為++的優先級高于解除引用操作符。

7,在使用條件操作符時,盡量避免寫出深度嵌套的條件操作符。另外條件操作符的優先級非常低,在表示式中使用時要注意加括号,比如:cout<<(i<j?i:j);

8,關于sizeof運算符。sizeof的運算結果是編譯時的常量,注意下面的代碼的值:

sizeof運算符小貼士:

9,在複合表達式求值時,要特别注意運算符的優先級與結合性。特别地,!=與==的優先級小于<=,>=等關系運算符。

10,類型轉換

1)隐式轉換

下面情況下,編譯器會自動地轉換運算對象的類型:

2)顯式轉換

1,和大多數語言一樣,c++提供了條件執行語句、重複執行相同代碼的循環語句和用于中斷前前控制流的跳轉語句。

2,在使用塊狀語句時注意,在塊狀語句内定義的變量作用域隻在塊狀區域内。特别地,在控制語句,比如if或for語句中,初始化或定義的變量,都隻有塊區域的作用域。

3,switch語句的使用。case标号必須是整形常量表達式,不允許在switch語句内定義變量如果在它下面還有case或default語句,因為這樣會在某些情況下,在沒有執行變量定義的case分支的情況下,執行變量定義下面case分支。除非把變量定義在代碼塊内。

4,在for循環中,如果有continue語句,會跳下continue後面的語句,但是不會跳變for語句中的計數器變化語句。

5,範圍for語句

範圍for語句是c++11新引入的内容,這種語句可以周遊容器或其他序列的所有元素。它的文法形式為:

其中expression表示的必須是一個序列,比如用花括号括起來的初始值清單或者vector或string等類型對象。這些類型的共同特點是擁有能傳回疊代器的begin和end成員。

declaration定義一個變量,序列中的每個元素都得能轉換成該變量的類型。確定類型相容最簡單的辦法是使用auto類型說明符,這個關鍵字可以令編譯器幫助我們指定合适的類型。如果需要對序列中的元素執行寫操作,循環變量必須聲明成引用類型。

下面是用範圍for語句來周遊一個vector的例子。

在使用範圍for時語句時,不能通過範圍for語句增加vector對象的元素。因為在範圍for語句中,預存了end()的值。一旦在序列中添加(删除)元素,end函數的值就可能變得無效了。

繼續閱讀