if 括号 if(...) 中语句的求值顺序是啥? [复制]
Posted
技术标签:
【中文标题】if 括号 if(...) 中语句的求值顺序是啥? [复制]【英文标题】:What is the order of evaluation of statements in a if bracket if(...)? [duplicate]if 括号 if(...) 中语句的求值顺序是什么? [复制] 【发布时间】:2013-08-29 07:46:31 【问题描述】:我有一个在程序开始时初始化为 NULL 的 char 指针,在程序中,char* 用于函数调用中,它可能指向一个 char 字符串,它可能指向 null char,它可能保持不变。 下面的陈述是否正确,如果表达式是从左到右计算的,应该是正确的。如果不是,则 strlen (charpointer) 是未定义的行为,如果 charpointer == NULL
if ( charpointer == NULL || strlen ( charpointer ) == 0 )
那么,它们是从左到右进行评估的吗?这是进行这种检查的正确方法吗?
【问题讨论】:
我确定这是多次重复。||
的操作数需要从左到右进行计算,使您的表达式安全(只要 charpointer
是空指针或指向字符串的有效指针)。对于大多数其他运算符,评估顺序是未指定的。
请注意,求值顺序与表达式用作if
语句中的条件无关;这完全是关于 ||
运算符。
【参考方案1】:
||
的求值顺序是从左到右,正如 Eric 提到的,这是 ||
和 &&
的特殊属性,大多数运算符不强制从左到右求值。如果左边的成功,它将不会评估右边的表达式,来自 C99 草案标准部分6.5.14
第 4 段:
不同于按位 |运算符,||运算符保证从左到右的评估;在第一个操作数的评估之后有一个序列点。 如果第一个操作数比较不等于 0,则不计算第二个操作数。
C++ 草案标准在5.15
部分有类似的语言第 1 段。
【讨论】:
【参考方案2】:从左到右的评估顺序。
在您的情况下,if 循环将从左到右检查第一个条件。如果第一个条件失败,它将从左到右检查第二个条件。
【讨论】:
并且评估顺序是由于逻辑或运算符,与if
或一般规则无关(如您的编辑所示)。
@SebastianRedl 感谢您的评论【参考方案3】:
评估顺序是,正如其他人从左到右表示的那样,但重要的是要认识到评估停止在可以确定逻辑表达式的真值(或缺乏真值)的点上。
这两种情况都是||和&&。
这一点特别重要,因为您不能假设将评估整个表达式,因此如果逻辑表达式的任何组件具有副作用(例如函数调用、增量、赋值等),它们不会全部必须执行。
【讨论】:
【参考方案4】:测试charpointer
是否为空。
if (charpointer == NULL) // etc.
如果要测试 charponter 是否指向 NULL 字符,则:
if ((charpointer != NULL) && (strlen(charpointer) == 0) // etc.
您可以将这些语句组合为:
if (charpointer == NULL)
else
if (strlen(charpointer) == 0) // etc.
或作为:
if ((charpointer != NULL) && (strlen(charpointer) == 0)) // etc.
或者你可以依靠你的代码正在做的短路。但是,charpointer == NULL 必须 的测试首先出现,因为表达式是从左到右计算的。
最后,在你写了相当多的 c 代码之后,你会了解到:
if (! charpointer) // etc.
与测试它是否等于 NULL 相同。所以,只是为了花哨而写出不可读的代码,那么:
if (!charpointer || !(strlen(charpointer)) // etc.
【讨论】:
【参考方案5】:评估过程的特点与if
声明完全无关。评估由表达式本身的属性决定。在if
中使用它的事实没有任何区别。
在你的情况下,有问题的表达是
charpointer == NULL || strlen ( charpointer ) == 0
它的行为主要由||
运算符的属性定义,它保证从左到右进行计算,第一个操作数的计算在第二个操作数的计算之前排序,并且具有“提前完成”(“short-电路”),以防第一个操作数的计算结果为 true
。
这意味着您原始帖子中的控制表达式是完全安全的。
【讨论】:
以上是关于if 括号 if(...) 中语句的求值顺序是啥? [复制]的主要内容,如果未能解决你的问题,请参考以下文章