[英]Using logical operators on integers in C
C 中整數的邏輯或和邏輯與運算符
你能解釋一下為什么 a,b,c 的值分別是 11,10,1 嗎? 為什么 b 的值保持為 10?
#include <stdio.h>
int main()
{
int a,b,c;
a=b=c=10;
c = a++ || ++b && ++c;
printf("%d %d %d",a,b,c);
return 0;
}
首先,讓我們看一下操作的順序。 邏輯 AND 運算符&&
的優先級高於邏輯 OR 運算符||
,所以表達式解析如下:
c = a++ || (++b && ++c);
接下來,兩個||
和&&
是短路運算符。 這意味着首先評估左側,如果結果可以單獨確定,則不評估右側。
所以a
從值 10 開始。a a++
計算為當前值 (10),同時增加a
作為副作用。 這意味着值 10 是||
的左側。 . 因為這是一個非零值,所以整個表達式的值為 1,並且不計算右側的++b && ++c
。 然后將此結果分配給 1。
所以最終結果是a
遞增到 11, c
被賦值為 1,因為這是||
的值表達式, b
不變。
這個表達
c = a++ || ++b && ++c;
可以等效地重寫為
c = ( a++ ) || ( ++b && ++c );
由於表達式 a++ 不等於 0,因此不計算第二個子表達式( ++b && ++c )
。
邏輯運算符的值 || && 是 1(真)或 0。
來自 C 標准(6.5.14 邏輯或運算符)
3 || 如果任一操作數比較不等於 0,則運算符應產生 1; 否則,它產生 0。結果具有 int 類型。
和
4 不同於按位 | 運算符,|| 運算符保證從左到右的評估; 如果計算第二個操作數,則在第一個和第二個操作數的計算之間存在一個序列點。 如果第一個操作數比較不等於 0,則不計算第二個操作數。
所以c
得到值1
並且a
增加了。
a=10 b=10 c=10
c = ( a++ || ++b) && (++c)
11 || ++b && ++c
a=11 b=10 c=10
c = 11 || ++b && ++c
11 && ++c
a=11 b=10 c=10
c = ( 11 || 11 ) && ++c
&& 11
a=11,b=10,c=10
**c= 11 && 11
a=11,b=10,c=1**
稍微擴展一下其他答案,您必須了解您的陳述實際上在做什么。
a=b=c=10;
c = a++ || ++b && ++c;
邏輯運算符自然采用 boolean 操作數,因此您的語句是(隱式):
c = ( a++ != 0 ) || ( ++b != 0 ) && ( ++c != 0 );
請注意,有趣的是,優先順序將 AND 運算符置於 OR 運算符之上——這意味着應該執行++b
。
然而,考慮到邏輯或的短路運算,已知第一項為true
,因此c = 1 (ie true)
。
--
當然,普通讀者會期望我在我的答案中添加 MISRA 傾向......
MISRA C:2012 規則 13.5 涵蓋了這個確切的場景......它指出邏輯&&
或||
的右手操作數運算符不應包含持久的副作用
因此,您的代碼的 MISRA 兼容版本將是:
a=b=c=10;
a++;
b++;
c++; // This is actually *dead code*
c = a || ( b && c );
printf("%d %d %d",a,b,c);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.