簡體   English   中英

&& 和 & 與 bool(s) 之間有什么區別嗎?

[英]Is there any difference between && and & with bool(s)?

在 C++ 中,在 bool(s) 之間執行&& (logical) 和& (bitwise) 之間有什么區別嗎?

bool val1 = foo();
bool val2 = bar();

bool case1 = val1 & val2;
bool case2 = val1 && val2;

case1case2是否相同,或者如果不同,它們究竟有何不同,為什么要選擇一個而不是另一個? 按位和布爾值可移植嗎?

標准保證false轉換為 0 並且true轉換為 1 作為整數:

4.7 積分轉換

...

如果目標類型是 bool,請參見 4.12。 如果源類型為 bool,則值 false 轉換為零,值 true 轉換為一。

所以你給出的例子中的效果保證是一樣的,並且是100%可移植的。

對於您給出的情況,任何體面的編譯器都可能生成相同的(最佳)代碼。

但是,對於 Boolean 表達式expr1expr2 ,通常expr1 && expr2expr1 & expr2相同是不正確的,因為&&執行“短路”評估。 也就是說,如果expr1評估為false ,則expr2甚至不會被評估。 這會影響性能(如果expr2很復雜)和行為(如果expr2有副作用)。 (但請注意,如果&形式避免條件分支,它實際上可以更快......出於性能原因玩弄這種東西幾乎總是一個壞主意。)

因此,對於您給出的特定示例,您將值加載到局部變量中然后對其進行操作,行為是相同的並且性能很可能是相同的。

在我看來,除非您特別依賴“短路”行為,否則您應該選擇最清楚地表達您的意圖的表述。 因此,使用&&進行邏輯 AND 和&進行位旋轉 AND,任何有經驗的 C++ 程序員都會發現您的代碼很容易理解。

使用邏輯和&&時,如果左側表達式為假,則不會計算右側表達式。

很多 C/C++/C# 代碼都依賴於此,例如: if (p != null && p->Foo())

對於您的示例,我將使用 case2(邏輯與)。 僅在處理位標志等時使用按位。

但是,如果 foo() 和 bar() 只返回 bool (0, 1) 那么 case1 和 case2 是一樣的。

有一個區別(嗯,兩個),雖然你不會在你的例子中看到它。

"&" 執行按位 "AND" 運算,這意味着0x1 & 0x1 = 0x1 ,但0x1 & 0x2 = 0x0 OTOH,“&&”是一個布爾/邏輯“AND”,意味着它將任何非零值視為 TRUE,因此0x1 && 0x1 = TRUE (通常表示為 -1,即全為 [或者可能表示為作為 C++ 中的 1,我忘記了]),而0x1 && 0x2 = TRUE也是如此。

此外,“&&”是短路的,這意味着如果第一個操作數為 FALSE,則不會計算第二個操作數。 因此,雖然FALSE & null_pointer->booleanField ==> null pointer exception ,但FALSE && null_pointer->booleanField = FALSE

在某些情況下使用按位運算可能會有輕微的性能優勢,但通常在評估 boolean 值時應使用雙 forms,以便您的代碼獨立於 boolean 值的精確表示。

&& ”是一個“條件邏輯“AND”,它僅在第一個表達式為 TRUE 時才計算第二個表達式

& ”是一個“非條件邏輯與”<--(如果您正在使用 boolean 表達式)它會評估兩個表達式


MOREOVER "&" 是一個“位”運算符,這意味着它在位級別上運行。

這個例子可以讓你更好地理解。

4 = 00000100  // 'four' bit set
5 = 00000101  // 'four' bit and 'one' bit set

00000100 (4) & // AND: only keep bits set in both
00000101 (5)
--------
00000100 (4)

00000100 (4) | // OR: keep bits set in either
00000101 (5)
--------
00000101 (5)

00000100 (4) ^ //  EXCLUSIVE OR: keep bits only set in one but not the other
00000101 (5)
--------
00000001 (1)

算法上沒有區別,但是使用 && 可以讓你“短路”檢查。 也就是說,要確定 case2,如果 val1 為假,那么編譯后的代碼沒有理由檢查 val2 的值以確定答案,其中 case1 需要實際的 AND 發生。

實際上,一個好的編譯器會識別這一點並生成相同的代碼……這取決於你的編譯器有多好。

邏輯運算符 && 和 || 在評估兩個表達式以獲得單個關系結果時使用。 運算符 && 對應於 Boolean 邏輯運算 AND。 如果兩個操作數都為真,則此運算結果為真,否則為假。

運算符 || 對應於 Boolean 邏輯運算 OR。 如果兩個操作數中的任何一個為真,則此操作結果為真,因此只有當兩個操作數本身都為假時才為假。

int a = 0, b = 10;

if(a == 1 && (b/a) == 0) cout << "This is okay\n"; // the 2nd expression is never checked as the first one is false

cout << "Bingo\n";

if(a == 1 & (b/a) == 0) cout << "This is not okay\n"; // program crashes here trying to divide by zero

cout << "Bingo\n"; // this will never get printed

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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