逻辑运算符

逻辑和

如果两个操作数都为非零,则执行两个操作数的逻辑布尔 AND,返回 1。逻辑 AND 运算符的类型为 int

0 && 0  /* Returns 0. */
0 && 1  /* Returns 0. */
2 && 0  /* Returns 0. */
2 && 3  /* Returns 1. */

逻辑或

如果任何操作数非零,则执行两个操作数的逻辑布尔 OR 运算,返回 1。逻辑 OR 运算符的类型为 int

0 || 0  /* Returns 0. */
0 || 1  /* Returns 1.  */
2 || 0  /* Returns 1.  */
2 || 3  /* Returns 1.  */

逻辑不

执行逻辑否定。逻辑 NOT 运算符的类型为 int。NOT 运算符检查至少有一位是否等于 1,如果是,则返回 0.否则返回 1;

!1 /* Returns 0. */
!5 /* Returns 0. */
!0 /* Returns 1. */

短路评估

&&||有一些共同的关键属性:

  • 在评估右手操作数(RHS)之前,对左手操作数(LHS)进行了全面评估,
  • 在左手操作数和右手操作数的评估之间有一个序列点,
  • 并且,最重要的是,如果左侧操作数的结果决定了整体结果,则根本不评估右侧操作数。

这意味着:

  • 如果 LHS 评估为’true’(非零),则不会评估||的 RHS(因为’true OR anything’的结果为’true’),
  • 如果 LHS 评估为(零),则不会评估 && 的 RHS(因为’false AND anything’的结果为’false’)。

这很重要,因为它允许你编写如下代码:

const char *name_for_value(int value)
{
    static const char *names[] = { "zero", "one", "two", "three", };
    enum { NUM_NAMES = sizeof(names) / sizeof(names[0]) };
    return (value >= 0 && value < NUM_NAMES) ? names[value] : "infinity";
}

如果将负值传递给函数,则 value >= 0 项的计算结果为 false,并且不评估 value < NUM_NAMES 项。