Namespaces
Variants

Logical operators

From cppreference.net

逻辑运算符对其操作数应用标准布尔代数运算。

运算符 运算符名称 示例 结果
! 逻辑非 ! a a 的逻辑否定
&& 逻辑与 a && b a b 的逻辑与
|| 逻辑或 a || b a b 的逻辑或

目录

逻辑非

逻辑非表达式的形式为

! 表达式

其中

expression - 任意 标量类型 的表达式

逻辑非运算符的类型为 int 。当 expression 求值为不等于零的值时,其结果为 0 ;当 expression 求值为等于零的值时,其结果为 1 。(因此 ! E 等价于 ( 0 == E )

#include <stdbool.h>
#include <stdio.h>
#include <ctype.h>
int main(void)
{
    bool b = !(2+2 == 4); // 非真
    printf("!(2+2==4) = %s\n", b ? "true" : "false");
    int n = isspace('a'); // 若 'a' 为空格则返回非零值,否则返回零
    int x = !!n; // "双感叹号",C语言中将整数映射到[0,1]范围的常用惯用法
                 //(所有非零值都会变为1)
    char *a[2] = {"non-space", "space"};
    puts(a[x]); // 现在x可以安全用作包含2个字符串的数组索引
}

输出:

!(2+2==4) = false
non-space

逻辑与

逻辑与表达式具有以下形式

左操作数 && 右操作数

其中

lhs - 任意标量类型的表达式
rhs - 任意标量类型的表达式,仅当 lhs 不等于 0 时才会被求值

逻辑与运算符的类型为 int ,当 lhs rhs 均不等于零时其值为 1 。否则(当 lhs rhs 或两者等于零时),其值为 0

lhs 求值之后存在一个 序列点 。如果 lhs 的比较结果等于零,则 rhs 完全不会被求值(即所谓的 短路求值

#include <stdbool.h>
#include <stdio.h>
int main(void)
{
    bool b = 2+2==4 && 2*2==4; // b == true
    1 > 2 && puts("this won't print");
    char *p = "abc";
    if(p && *p) // 常见C语言惯用法:如果p非空
                // 且p不指向字符串结尾
    {           // (注意得益于短路求值特性,此处
                //  不会尝试解引用空指针)
    // ...      // ... 则执行字符串处理操作
    }
}

逻辑或

逻辑或表达式的形式为

左操作数 || 右操作数

其中

lhs - 任意标量类型的表达式
rhs - 任意标量类型的表达式,仅当 lhs 0 比较相等时才会被求值

逻辑或运算符的类型为 int ,当 lhs rhs 与零比较不相等时,其值为 1 。否则(当 lhs rhs 均与零比较相等时),其值为 0

lhs 求值后存在一个 序列点 。若 lhs 的比较结果不等于零,则 rhs 完全不会被求值(即所谓的 短路求值

#include <stdbool.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
int main(void)
{
    bool b = 2+2 == 4 || 2+2 == 5; // true
    printf("true or false = %s\n", b ? "true" : "false");
    // 逻辑或运算符可类似Perl的"or die"用法,只要右侧操作数具有标量类型
    fopen("test.txt", "r") || printf("could not open test.txt: %s\n", strerror(errno));
}

可能的输出:

true or false = true
could not open test.txt: No such file or directory

参考文献

  • C11 标准 (ISO/IEC 9899:2011):
  • 6.5.3.3 一元算术运算符 (页: 89)
  • 6.5.13 逻辑与运算符 (页: 99)
  • 6.5.14 逻辑或运算符 (页: 99)
  • C99 标准 (ISO/IEC 9899:1999):
  • 6.5.3.3 一元算术运算符 (页: 79)
  • 6.5.13 逻辑与运算符 (页: 89)
  • 6.5.14 逻辑或运算符 (页: 89)
  • C89/C90 标准 (ISO/IEC 9899:1990):
  • 3.3.3.3 一元算术运算符
  • 3.3.13 逻辑与运算符
  • 3.3.14 逻辑或运算符

参考

运算符优先级

常用运算符
赋值 自增
自减
算术 逻辑 比较 成员
访问
其他

a = b
a + = b
a - = b
a * = b
a / = b
a % = b
a & = b
a | = b
a ^ = b
a <<= b
a >>= b

++ a
-- a
a ++
a --

+ a
- a
a + b
a - b
a * b
a / b
a % b
~a
a & b
a | b
a ^ b
a << b
a >> b

! a
a && b
a || b

a == b
a ! = b
a < b
a > b
a <= b
a >= b

a [ b ]
* a
& a
a - > b
a. b

a ( ... )
a, b
( type ) a
a ? b : c
sizeof


_Alignof
(自 C11 起)
(至 C23 止)

alignof
(自 C23 起)

另请参阅

C++ 文档 关于 逻辑运算符