簡體   English   中英

在 C 中對整數使用邏輯運算符

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM