C中条件语句内的位运算符和逻辑运算符之间有什么区别?

pgm*_*ank 0 c bitwise-operators logical-operators conditional-statements

网上有很多问题涉及按位和逻辑运算符之间的差异.希望我做了一个很好的搜索,当在条件语句中使用时,他们都没有专注于它们是否相同,也没有专门用于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");
    }
}
Run Code Online (Sandbox Code Playgroud)

该程序的输出是:

_______AND_______
Logical   Bitwise
true      true
false     false
false     false
false     false
_______OR________
Logical   Bitwise
true      true
true      true
true      true
false     false
Run Code Online (Sandbox Code Playgroud)

这证明了按位运算符和逻辑运算符之间没有区别.更改TRUEFALSE宏的定义以包括剩余的比较运算符,可以看出再没有区别.

因此,如果存在差异,这些可能与编译器解释语句或代码效率的方式相关联.

总之,在特定情况下,当我们在条件语句中的两个或多个比较操作结果之间有一个按位或逻辑运算符时,我们应该使用哪两个,主要是为了提高效率?

Joh*_*ica 7

你只是检查值01.尝试其他值,你会看到差异.

int a = 4, b = 2;

puts(a && b ? "true" : "false");
puts(a & b  ? "true" : "false");
Run Code Online (Sandbox Code Playgroud)

这打印:

true
false
Run Code Online (Sandbox Code Playgroud)

按位运算符仅适用于整数.逻辑运算符可以与指针,浮点数和其他非整数类型一起使用.

还有短路.如果第一个操作数足够,逻辑运算符将不会计算它们的第二个操作数.

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");
}
Run Code Online (Sandbox Code Playgroud)

这打印:

a
false
---
a
b
false
Run Code Online (Sandbox Code Playgroud)

注意b使用时如何打印&.没有短路所以&调用两个函数,而&&只调用a().

与更微妙的说明不同&&,&不会对其操作数施加评估顺序.输出同样可以拥有ab打印输出逆转.

a
false
---
b
a
false
Run Code Online (Sandbox Code Playgroud)

如果你把所有这些差异放在一边,那么是的,运算符是等价的.在这种情况下,不要担心效率.使用语义正确的运算符:逻辑运算符.

(如果它有助于缓解你的想法,那么效率就没有区别.编译器非常聪明,无论你使用哪种运算符,编译器都会发出最佳字节码来评估这些表达式.)