標籤:解釋 簡單 提升 類型 賦值運算 c99 左值 改變 而且
本節主要講基本運算子的優先順序,結合性和求值順序。
先看一個運算式- (1 + 2) * 3 + (4 + 5 * (6 + 7 ))
記住你對它的運算過程,看完下面的內容之後,也許你會用不同的方式來看待這個運算式。
基本運算子 = + - * /
C中沒有指數運算。
運算子操作的是運算元,運算元就是放在運算子兩側的東西。
(1) 賦值運算子 =
year = 2016; 讀作將值2016賦給year,而非year等於2016。
=將2016賦給變數year,是從右至左的,即=具有右結合性。
2016 = year; 這種寫法是錯誤的,不能給常量賦值。
那麼,=的左邊應該放什麼樣的對象?
答案是必須是一個儲存位置。year是一個變數名,代表的是一個地址,這裡可以儲存值。
year可以被賦值,我們稱這類可以被賦值的實體為可修改的左值。
右值指可以賦給可修改的左值的量,當然,右值就不必在乎可不可以修改了。
=運算子的運算元有哪些呢?
(2)加法運算子 +
+將兩側的值加到一起。
+的運算元可以是變數也可以是常量。
(3)減法運算子 –
-從它前面的數減去它後面的數。
-的運算元可以是變數也可以是常量。
(4)符號運算子 + -
先看一個運算式:
-(1990 - 2016)
第一個減號-和第二個減號-含義相同嗎?
答案是不相同。
+ - 作用於兩個運算元時稱為二元算數運算子,當它們作用於一個運算元時,稱為一元符號運算子。
-作用於一個運算元時,用於指示或改變其代數符號。
一元運算子+在C90標準才加進C中,這之前是不允許+1990這種語句的。一元運算子+不改變它的運算元的值或符號。
(5)乘法運算子 *
*將左右兩個運算元相乘。
*的運算元可以是變數也可以是常量。
(6)除法運算子 /
在講前面的運算子時,為什麼一直強它們調運算元呢?因為有些運算子不能作用於某些類型,也有些運算子作用於不同的運算元結果不同。
/左邊的值被右邊的值除。
/作用於浮點數,結果為浮點數,如2.0/3.0的結果為0.666667(為什麼不是0.666666?)
/作用於整型數,結果為整數,如2/3的結果為0,而不是0.6或0.7,因為自從C99之後,整數除法採用了趨零截尾的方式,直接截掉小數點後的數字。
2.0/3.0, 2/3結果都可知了,那麼2.0/3或2/3.0的結果是什嗎?
先有一個這樣的意識,如果算術運算子兩側運算元的類型不同,會引起類型轉換。
2.0/3或2/3.0中,首先將整型值提升為浮點型,然後再做除法運算,結果為0.666667(為什麼不是0.666666?)
既然是趨零結尾,那麼C中怎麼實現四捨五入呢?
可以巧妙的利用趨零結尾的方式,對正數a用(int)(a+0.5)方式,對負數a用(int)(a-0.5)的方式。
(7)運算子的優先順序,優先順序和求值順序
下面運算式的結果是什嗎?運算順序是怎樣的?
- (1 + 2) * 3 + (4 + 5 * (6 + 7 ))
按照我們正常計算的思維,會先算2*3,第一個加號之前的結果為-6,然後再算後面括弧裡運算式的值。
在計算上面的運算式之前,我們先來看一個簡單的運算式,來解釋一些概念。
2*3+4*5
想一下,在你剛剛計算的時候,什麼時候用到了優先順序?
當兩個運算子共用同一個運算元的時,優先順序決定了求值順序。2*3+4*5中,4為+和*共用,優先順序就規定先對4進行乘法運算,這保證兩個*運算在+運算之前進行,在2*3+4*5這個運算式中,優先順序的作用到此為止了。
接著考慮,2*3和4*5先計算哪個?
你可能會認為是先計算2*3,理由是加法運算子+的結合性。+作為二元運算子時,結合性是從左至右,所以先計算+的左邊,再計算右邊。如果你這樣想,就對結合性理解有誤了。
什麼是運算子的結合性?
我們看錶達式2*3+4*5-6*7,乘法運算過後,運算式簡化為6 + 20 - 42,這時應該先計算6+20,再計算26-42,因為有相同優先順序的+和-共用同一運算元20,所以+發揮了結合性的作用。記住,結合性適合於共用同一運算元的運算子(注意與優先順序的作用進行區分)。在2*3+4*5中,兩個*不共用同一運算元,而且先進行乘法運算,簡化為6+20之後,沒有運算元是共用的。所以上邊的想法就有誤了。
先計算哪個乘法?
2*3+4*5中,到底先進行哪個乘法運算呢?答案是不確定,看具體的實現,由設計者決定。特別需要注意的是,優先順序只保證乘法在加法前進行,並不確定兩個乘法哪個先進行。
瞭解了上面的概念,現在我們來看錶達式
- (1 + 2) * 3 + (4 + 5 * (6 + 7 ))
根據優先順序,先計算圓括弧裡的運算式,這裡面有三個圓括弧(),先計算哪個呢?
可以確定的是紅色括弧裡的運算式在綠色括弧裡進行,但藍色括弧和綠色括弧之間誰先被運算,依賴於實現。
注意,前半部分(1+2)運算完之後是-3*3,然後第一個3和它前面的一元符號運算子結合為-3,然後再乘以3。
C之旅(一)運算子——優先順序,結合性和求值順序