* 和 + 分别等同于 && 和 ||在布尔操作数上?

Are * and + equivalent to, respectively, && and || on Boolean operands?

a[8] 是一个布尔数组。我正在尝试计算如下所示的布尔表达式。

bool a[8];
.....
bool result=a[0]*(a[3]+a[6]*(a[4]+a[7]*a[5]))+a[1]*(a[6]*a[3]+a[4]+a[7]*a[5])+a[2]*(a[5]+a[7]*(a[4]+a[6]*a[3]));

表达式很长,但概念上并不复杂。唯一的错误是,当我将表达式中的 * 替换为 && (在这两种情况下我都期望逻辑与)或将 + 替换为 || 时,结果似乎有所不同(期待逻辑或)。

我不确定哪些是正确的,布尔运算符或乘法、加法等数学符号。更糟糕的是,none 给出任何错误,即编译器对两者都满意。哪个更安全正确?

对于 bool 个操作数,它们 几乎 相同。但有细微差别:

  1. *+ 会将 bool 类型参数扩展为 int 类型。

  2. 表达式a || b的类型是bool,而a + bint&&*.

  3. 同上
  4. *+ 不是排序点,而 &&|| 是。

  5. *+ 不是 short-circuited,而 &&|| 是。

  6. 它们在运算符优先级中的位置截然不同table。所以替换并不简单。

  7. 如果 a 是一个 bool,并且 b 也是一个 bool 但未初始化,则 [=15= 的行为] 已定义,但 a + bundefined,因为 bool can 在 C++ 中包含陷阱表示。 &&*.

  8. 可以使用类似的表达式
  9. 很长的 a + b + c + ... 链可能会溢出 int 类型,其行为未定义。

(3) 表示 a++ * a++ 是未定义的行为,但 a++ || a++ 不是。

(这里不相关但值得注意:请注意 &&|| 如果过载则失去短路 属性。

除了逻辑运算符中的short-circuiting,这在这里没有区别,解释行为变化的关键区别是operator precedence

当您将 * 替换为 &&,或将 + 替换为 || 时,优先顺序会发生变化:* 变为 优先级高于 +,但 && 具有 低于 优先级 +。这就是为什么您需要将表达式完全括起来以强制执行所需的操作顺序,仅将 * 替换为 &&.

*+ 替换为 &&|| 将使两个运算符的相对优先级保持相同,因此您最终会得到相同的结果.