8.5.2 短路布尔运算符

结合在 ifwhile 条件中到标量值的隐式转换,Octave 的逐元素布尔运算符通常足以执行大多数逻辑运算。然而,有时希望一旦能够确定整体真值就停止对布尔表达式求值。Octave 的 短路 布尔运算符正是以这种方式工作的。

boolean1 && boolean2

先对表达式 boolean1 进行求值,并使用等价于 all (boolean1(:)) 的操作将其转换为标量。如果 boolean1 不是逻辑值,则当其值为非零时视为真,值为零时视为假。如果 boolean1 是一个数组,则仅当它非空且所有元素均为非零时才视为真。如果 boolean1 求值为假,则整个表达式的结果为假。如果它为真,则对表达式 boolean2 进行与 boolean1 相同方式的求值。如果它为真,则整个表达式的结果为真。否则整个表达式的结果为假。

警告: 与求值 all (boolean1(:)) 等价的一个例外情况是当 boolean1 是空数组时。为了与 MATLAB 兼容,空数组的真值始终为 false,因此 [] && true 求值为 false,尽管 all ([])true

boolean1 || boolean2

先对表达式 boolean1 进行求值,并使用等价于 all (boolean1(:)) 的操作将其转换为标量。如果 boolean1 不是逻辑值,则当其值为非零时视为真,值为零时视为假。如果 boolean1 是一个数组,则仅当它非空且所有元素均为非零时才视为真。如果 boolean1 求值为真,则整个表达式的结果为真。如果它为假,则对表达式 boolean2 进行与 boolean1 相同方式的求值。如果它为真,则整个表达式的结果为真。否则整个表达式的结果为假。

警告: 空矩阵的真值始终为 false,详细信息请参见上一个列表项。

在确定表达式的整体真值之前,可能不会对两个操作数都进行求值——这一特性可能很重要。例如,在表达式

a && b++

中,变量 b 的值仅当变量 a 为非零时才会递增。

这可以用来编写更简洁的代码。例如,可以这样写

function f (a, b, c)
  if (nargin > 2 && ischar (c))
    ...

而不必使用两个 if 语句来避免尝试对不存在的参数求值。例如,如果没有短路特性,则需要写成

function f (a, b, c)
  if (nargin > 2)
    if (ischar (c))
      ...

写成

function f (a, b, c)
  if (nargin > 2 & ischar (c))
    ...

将会导致错误——如果使用一个或两个参数调用 f,因为 Octave 将被迫尝试对运算符 ‘&’ 的两个操作数都进行求值。

MATLAB 具有特殊行为,允许运算符 ‘&’ 和 ‘|’ 在用于 ifwhile 语句的真值表达式时执行短路求值。为了兼容性,Octave 的行为相同,但是,强烈不鼓励以这种方式使用 ‘&’ 和 ‘|’ 运算符,并且会发出警告。相反,您应该使用始终具有短路行为的 ‘&&’ 和 ‘||’ 运算符。

最后,Octave 不支持三元运算符(?:)。如果短路特性不重要,可以用 ifelse 函数替代。

 
M = merge (mask, tval, fval)
M = ifelse (mask, tval, fval)

根据 mask 的值,合并 true_valfalse_val 中的元素。

如果 mask 是逻辑标量,则另外两个参数可以是任意值。否则,mask 必须是逻辑数组,而 tvalfval 应当是匹配类型的数组或元胞数组。在标量 mask 的情况下,如果 mask 为真,则返回 tval,否则返回 fval

在数组 mask 的情况下,tvalfval 都必须是标量或维度与 mask 相等的数组。结果构造如下:

result(mask) = tval(mask);
result(! mask) = fval(! mask);

mask 也可以是任意数值类型,此时它首先被转换为逻辑类型。

编程说明:ifelsemerge 的别名,可以互换使用。

另请参阅: logicaldiff


版权所有 © 2024-2026 Octave中文网

ICP备案/许可证号:黑ICP备2024030411号-2