《C語言解惑》一1 3 邏輯操作符和增量操作符

2021-09-23 16:50:01 字數 2854 閱讀 9307

請問,下面這個程式的輸出是什麼?

輸出:

1                             (1.3.1)

解惑1.3 邏輯操作符和增量操作符

初始值:x = 2, y=1, z=0

x = x&&y || z  按照操作符的優先順序和關聯規則進行繫結。

x = (x&&y) || z

x = ((x&&y) || z)

(x = ((x&&y) || z))

(x = ((true&&true) || z))   邏輯操作符的求值順序是從左到右。邏輯操作符的運算元如果是0,則解釋為false;如果是非零值,則解釋為true。

(x = (true || z))   只有兩個運算元都是true,邏輯與(&&)的結果才會是true;其他情況的求值結果都將是false。

(x = (true ||任意值))  只要有乙個運算元是true,那麼不管另乙個運算元是什麼,邏輯或(||)的結果都將是true。因此,我們不必再對這個表示式繼續求值了。

(x = true)

(x = 1)

再談define:這個程式裡的define語句與前乙個程式裡的define語句有所不同:這個程式裡的「print」是乙個帶引數的巨集。在遇到帶引數的巨集時,c語言的預處理器將分兩步進行替換:先把巨集定義裡的形式引數替換為實際引數,再把巨集呼叫替換為巨集定義體。

在這個程式裡,「print」巨集有乙個形式引數int。「print(x)」是使用實際引數「x」進行的「print」呼叫。在擴充套件「print」呼叫的時候,c語言預處理器會先把巨集定義裡的所有「int」替換為「x」,再把巨集呼叫「print(x)」替換為結果字串「printf``("%dn", x)」。請注意,形式引數int並不是匹配單詞「printf」裡的「int」字元的。這是因為巨集定義裡的形式引數是識別符號——具體到這個例子,形式引數int只對識別符號int進行匹配和替換。

初始值:x = 1, y=1, z=0

x || ! y&&z

x || (! y)&&z  對操作符和運算元進行繫結。

x || ((! y)&&z)

(x || ((! y)&&z))

(true || ((! y)&&z))  按從左到右的順序求值。

(true ||任意值)

true,即1

初始值:x = 1,y=1

z = x ++ - 1

z = (x ++) – 1  對操作符和運算元進行繫結。

z = ((x ++) - 1)

(z = ((x ++) - 1))

(z = (1 - 1)),此時x=2  出現在運算元右邊的「++」操作符是所謂的「後」遞增操作符:先在表示式裡用該運算元完成有關的計算,再對它進行遞增。

(z = 0)

初始值:x = 2, y=1, z=0

z += - x ++ + ++ y

z += - (x ++) + (++ y)   一元操作符的關聯是從右到左,因而「++」操作符將先於一元操作符「-」得到繫結。(事實上,如果先去繫結「-」操作符的話,這個表示式將無法成立。這是因為「++」和「--」操作符都要求以乙個變數(更準確地說,以乙個「左值」[1])作為其運算元。「x」是乙個左值,但「-x」不是。)

z += (- (x ++)) + (++ y)

z += ((- (x ++)) + (++ y))

(z += ((- (x ++)) + (++ y)))

(z += ((-2) + 2)),此時x=3, y=2

(z += 0)

(z = 0 + 0)

(z = 0)

按照從內到外的順序依次求值。

關於記號:電腦程式的源**文字是由一系列記號構成的,而編譯乙個程式的第一項工作就是把那些記號乙個乙個地分解開。這在絕大多數場合都沒有什麼困難,但有些字串行可能會讓人感到困惑。比如說,如果上面這個例子裡的表示式有一部分根本沒有空格——就像下面這樣:

x+++++y

那麼,這個沒有空格的表示式與有空格的表示式還會是等價的嗎?

為避免產生二義性,如果乙個字串能夠解釋為多個操作符,c語言編譯器將按照「構成操作符的字元個數越多越好」的原則來作出選擇。根據這一原則,「x+++++y」解釋為:

x++ ++ + y

而這已經不是乙個合法的表示式了。

初始值:x = 3,z=0

z = x / ++ x

z = x / (++ x)

z = (x / (++ x))

(z = (x / (++ x)))

如果你還像以前那樣按照從內到外的順序對這個表示式進行求值,即先對x進行遞增,然後作為除數、用x作被除數去進行除法計算。問題是:作為被除數的x到底是幾?是3還是4?換個問法,被除數到底是遞增前的x值,還是遞增後的x值?請注意,c語言並沒有對這種「***」作出明確的規定,而是由c編譯器的編寫者決定的[2]。這個例子的教訓是:如果你無法斷定會不會產生***,那麼就盡量不要寫這樣的表示式。

c語言 位操作符和邏輯操作符

按位與 按位或 按位異或 注 他們的運算元必須是整數。兩個整數字元位有假 0 就為假 0 只有全為真 1 就為真 1 舉個例子 老師叫兩個學生來辦公室,說張三與 李四過來,如果只乙個人過去就不滿足老師說的話 為假 必須兩個人都過去 為真 兩個整數字元位只要有真就為真,只有全為假 0 就為假 0 舉個...

關係操作符和邏輯操作符

關係操作符和邏輯操作符使用算術或指標型別的運算元,並返回bool 型別的值。操作符功能用法 logical not 邏輯非 expr less than 小於 expr expr less than or equal 小於等於 expr expr greater than 大於 expr expr ...

c語言中自增操作符與自減操作符

初學c語言的朋友肯定對自增操作符和自減操作符感到頭疼,一下就討論一下自增操作符,自減操作符。在程式設計中遇到的問題最好就是遍個程式試試。include int main 終端輸出結果是 4 2,那麼可以說明c先自增成2,然後加法操作用的是自增後的值2。include int main 而這個程式只是...