前言:
本文一些內容是根據自己理解來寫的,沒有完全查證,不過應該也差不多了。
要想完全理解表示式,還是有很多東西要理解的,可謂博大精深。
在中的運算子和表示式 一文中,我已經提到了理解表示式最核心的幾個概念,編譯方式,運算子優先順序,運算子結合性,還有特殊的自增自減運算子等等。
在運算子過載 一文中,我也提到,運算子過載不能改變運算子的優先順序,結合性,以及預算物件數目。
然而,掌握了這些,依然不足以完全理解表示式的運算順序,特此補充。
首先重申乙個重要概念,運算子的優先順序和結合性,相當於是規定了如何新增括號,而不是規定運算順序。
比如,(a+b)*(c+d),是先計算a+b還是先計算c+d呢?這個運算順序不影響結果,但是(a=b)+(b=a)呢?這個運算順序就影響結果了。
這就是本文要討論的內容——同級表示式的運算順序,是c語言未定義的行為,具體順序由編譯器決定。
不難發現,同級表示式的計算順序會影響結果的,有3類:
(1)func1+func2
2個函式的執行順序可能會有影響
(2)含賦值運算子的表示式
比如(a=b)+(b=a)
(3)含自增運算子++或者自減運算子--的表示式
自增自減我認為是特殊的運算子,帶有賦值屬性,優先順序又是個謎,這裡做乙個單獨討論
(1)表示式中的自增自減
如果++和--的數目都不超過1,那是沒有歧義的,字首式就是在表示式之前計算,字尾式就是在表示式之後計算,
但是有乙個數目超過1,但是乙個是字首,乙個是字尾,其實也是沒有歧義的。
在自增字首、自增字尾、自減字首、自減字尾這4個裡面,如果有乙個的數量超過1,那就是未定義的行為。
ps:有乙個現象我依舊沒搞清楚,在我的編譯器中,
++--a 是合法的,++a-- 不合法,++(a--) 不合法,(++a)-- 合法,a++-- 不合法,(a++)-- 不合法
(2)函式傳參中的自增自減
比如func(a++,++a),應該是未定義的順序。
(3)cin和cout中的自增自減
int a=1;
cout《輸出:21
怎麼理解這個式子呢?
cout是乙個物件,它過載了左移運算子<<,返回的是this指標指向的本身這個cout物件
因為過載是不改變優先順序和結合性的,所以上述**相當於
int a=1;
(cout《說實話,這個式子輸出21,是挺出乎我的意料的。
我猜測,這個可能是先把a++作為引數傳進去了,再把a作為引數傳進去了。
學海無涯啊,乙個如此簡單的表示式,學程式設計6年了才發現自己根本不懂。
C語言 自增( ) 自減( )運算
1.作用 自增運算使單個變數的值增 自減運算使單個變數的值減 2.用法與運算規則 自增 自減運算子都有兩種用法 1 前置運算 運算子放在變數之前 變數 變數 先使變數的值增 或減 然後再以變化後的值參與其它運算,即先增減 後運算。2 後置運算 運算子放在變數之後 變數 變數 變數先參與其它運算,然後...
c 自增自減運算彙總(經典)
c 自增自減問題 在程式設計中,經常遇到 i i 1 和 i i 1 這兩種極為常用的操作。變數i被稱為 計數器 用來記錄完成某一操作的次數。c語言為這種計數器操作提供了兩個更為簡潔的運算子,即 和 分別叫做自增運算子和自減運算子。它們是從右向左結合的一元算術運算子,優先順序為2。學習和應用這兩個運...
printf多個自增自減表示式的底層實現原理
提起i i 和 i i 相信大家非常熟悉。兩者的區別是 前者是先賦值,然後再自增或自減 後者是先自增或自減,後賦值。但是當printf函式與多個自增自減表示式結合起來,編譯器實現 i i 和 i i 的原理你真的了解嗎?今天,我們從一道有意思的題目揭開printf多個自增自減表示式底層實現的面紗.源...