【发布时间】:2011-01-28 04:54:06
【问题描述】:
在带有多个条件的if语句中,如果第一个条件的结果明确,是否执行第二个条件?
示例:
if(i>0 && array[i]==0){
}
如果我交换条件,则 i 的负值可能会发生段错误,但这样不会发生段错误。我可以确定这总是有效还是必须使用嵌套的 if 语句?
【问题讨论】:
标签: c
在带有多个条件的if语句中,如果第一个条件的结果明确,是否执行第二个条件?
示例:
if(i>0 && array[i]==0){
}
如果我交换条件,则 i 的负值可能会发生段错误,但这样不会发生段错误。我可以确定这总是有效还是必须使用嵌套的 if 语句?
【问题讨论】:
标签: c
这种类型的评估称为short-circuiting。 一旦结果 100% 明确,就不会继续评估。
这实际上是一种常见的编程技术。 例如,在 C++ 中,您经常会看到如下内容:
if (pX!=null && pX->predicate()) { bla bla bla }
如果您更改了条件的顺序,您可能会在空指针上调用方法并崩溃。当您有一个指向该结构的指针时,C 中的一个类似示例将使用该结构的字段。
你可以用 or 做类似的事情:
if(px==null || pX->isEmpty()} { bla bla bla }
这也是在 if 条件下避免副作用通常是一个好主意的原因之一。
例如假设你有:
if(x==4 && (++y>7) && z==9)
如果x是4,那么无论z或y的值如何,y都会递增,但如果x不是4,则根本不会递增.
【讨论】:
if (function_that_returns_neg_on_error(param1, param2) < 0) { perror("function"); return -1;}
运算符&& 和|| 保证在计算右侧表达式之前将完全计算左侧表达式(并应用所有副作用)。换句话说,运算符引入了一个序列点。
此外,如果表达式的值可以从 lhs 确定,则不计算 rhs。换句话说,如果你有一个像x && y 这样的表达式,并且 x 的计算结果为 0(假),那么无论 y 是什么,表达式的值都是假的,所以不会计算 y。
这意味着像x++ && x++ 这样的表达式是明确定义的,因为&& 引入了一个序列点。
【讨论】:
来自草案 3485 (n3485.pdf) 它明确指出
5.14 逻辑与运算符 [expr.log.and]
logical-and-expression: inclusive-or-expression logical-and-expression && inclusive-or-expression
- && 运算符组从左到右。这 操作数都根据上下文转换为 bool(第 4 条)。这 如果两个操作数都为真,则结果为真,否则为假。不像 &, && 保证从左到右的评估:第二个操作数不是 如果第一个操作数为假,则进行评估。
- 结果是布尔值。如果 第二个表达式被评估,每个值计算和边 与第一个表达式相关的效果在每个表达式之前排序 与第二个相关的价值计算和副作用 表达。
【讨论】: