[英]What is the difference between bitwise and logical operators inside conditional statements in C?
網上有許多問題涉及到按位運算符和邏輯運算符之間的差異。 希望我做了一個很好的搜索,它們中沒有一個專門用於在條件語句中使用它們時是否相同,也不專門涉及C語言。 大多數人提到C ++和C#,但我不知道相同的答案是否也適用於C語言。
這是我編寫的示例代碼,用於測試發生的情況:
// Difference between logical && and bitwise & //
#include <stdio.h>
#define TRUE 123>45
#define FALSE 4>2342
void print_tt(int table[][4]);
int main(void) {
int and_tt[2][4]; // AND truth table
int or_tt[2][4]; // OR truth table
// Create truth table for logical and bitwise AND operator all in one 2d array
and_tt[0][0] = TRUE && TRUE ? 1 : 0;
and_tt[0][1] = TRUE && FALSE ? 1 : 0;
and_tt[0][2] = FALSE && TRUE ? 1 : 0;
and_tt[0][3] = FALSE && FALSE ? 1 : 0;
and_tt[1][0] = TRUE & TRUE ? 1 : 0;
and_tt[1][1] = TRUE & FALSE ? 1 : 0;
and_tt[1][2] = FALSE & TRUE ? 1 : 0;
and_tt[1][3] = FALSE & FALSE ? 1 : 0;
// Create truth table for logical and bitwise OR operator all in one 2d array
or_tt[0][0] = TRUE || TRUE ? 1 : 0;
or_tt[0][1] = TRUE || FALSE ? 1 : 0;
or_tt[0][2] = FALSE || TRUE ? 1 : 0;
or_tt[0][3] = FALSE || FALSE ? 1 : 0;
or_tt[1][0] = TRUE | TRUE ? 1 : 0;
or_tt[1][1] = TRUE | FALSE ? 1 : 0;
or_tt[1][2] = FALSE | TRUE ? 1 : 0;
or_tt[1][3] = FALSE | FALSE ? 1 : 0;
puts("_______AND_______");
puts("Logical Bitwise");
print_tt(and_tt);
puts("_______OR________");
puts("Logical Bitwise");
print_tt(or_tt);
}
// prints the truth table of the bitwise and logical operator given side by side
void print_tt(int table[][4]) {
int i;
for(i=0; i<4 ; ++i) {
printf("%-10s%s\n", table[0][i] ? "true" : "false",
table[1][i] ? "true" : "false");
}
}
該程序的輸出為:
_______AND_______
Logical Bitwise
true true
false false
false false
false false
_______OR________
Logical Bitwise
true true
true true
true true
false false
這證明了按位運算符和邏輯運算符之間沒有區別。 更改TRUE
和FALSE
宏的定義以包括其余的比較運算符,您可以看到再次沒有區別。
因此,如果存在差異,則這些差異可能與編譯器解釋語句的方式或代碼的效率相關。
總而言之,在特定情況下,如果在條件語句中比較操作的兩個或多個結果之間有按位或邏輯運算符,則應使用兩者中的哪一個,主要是為了提高效率?
您只檢查值0
和1
。 嘗試其他值 ,您會發現差異。
int a = 4, b = 2;
puts(a && b ? "true" : "false");
puts(a & b ? "true" : "false");
打印:
true
false
按位運算符僅適用於整數 。 邏輯運算符可與指針,浮點數和其他非整數類型一起使用。
也有短路現象 。 如果第一個操作數足夠,則邏輯運算符不會評估其第二個操作數。
int a() { puts("a"); return 0; }
int b() { puts("b"); return 1; }
int main() {
puts(a() && b() ? "true" : "false");
puts("---");
puts(a() & b() ? "true" : "false");
}
打印:
a
false
---
a
b
false
注意使用&
時b
的打印方式。 沒有短路,因此&
調用兩個函數,而&&
僅調用a()
。
而且,與&&
不同的是, &
不會在其操作數上施加求值順序 。 輸出也可以將a
和b
打印輸出反轉。
a
false
---
b
a
false
如果將所有這些差異放在一邊 ,那么是的,這些運算符是等效的。 在這種情況下, 不必擔心效率 。 使用在語義上正確的任何運算符:邏輯運算符。
(如果您可以放心使用,那么效率不會有任何區別。編譯器非常聰明,並且肯定會發出最佳字節碼來評估這些表達式,無論您使用哪種運算符。)
1101 & 0010 = 0000, 1101 && 0010 = True
1101 | 0010 = 1111, 1101 || 0010 = True
原因是逐位比較每個位,而邏輯將整個位字符串視為一個對或錯。 當查看一位的位串時,邏輯運算符和按位運算符之間確實沒有區別。 另一種思維方式是按位運算符是從整數到整數的函數,而邏輯運算符是從布爾到布爾的函數。
通過調用table[0][i] ? "true" : "false"
table[0][i] ? "true" : "false"
您將整數轉換為一位。 如果將其保留為整數,則會看到兩種類型的運算符之間的差異。
&&
是布爾運算符,而&
是按位運算符。
&
是對兩個整數進行的和運算。 例如: 1100 & 1001 = 1101
,所以12 & 9 = 13
。
&&
僅檢查(左右)值是否均為TRUE(即非零)。
例如1 & 2
是0
,因為1和2的二進制和是0。例如: 01 & 10 = 00
1 && 2
就像TRUE && TRUE
,也等於true。 因此,使用&&
,左值和右值都首先“轉換”為布爾表達式,然后進行比較。
同樣,不要忘記編譯器能夠短路&&
表達式。 像這個:
bool variable = isValid && compareSomething()
正確的值不會被評估,因為它不需要評估。 第一個已經明確聲明variable
isValid
,只要isValid
為true即可。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.