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(...) 中语句的求值顺序是啥? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

初始化列表中元素的求值顺序

php if语句没有中括号 那表示的是啥意思

栈的应用 -- 无括号表达式的求值

if-else语句中,if和else的配对原则各是啥

C++17 中函数指针的求值顺序

关于使用共享指针的评估顺序