if括号if(..)中语句的求值顺序是什么

What is the order of evaluation of statements in a if bracket if(...)?

本文关键字:if 顺序 是什么 语句 括号      更新时间:2023-10-16

在程序开始时,我有一个初始化为NULL的char指针,在程序中,char*在函数调用中使用,它可能指向一个字符串chars,也可能指向NULL char,并且可能保持不变。如果表达式是从左到右计算的,那么下面的语句正确吗。如果不是,则strlen(charpointer)是未定义的行为,如果charpointer==NULL

if (  charpointer == NULL || strlen ( charpointer ) == 0  )

那么,他们的评价是从左到右的吗?这样检查正确吗?

||的求值顺序是从左到右,正如Eric提到的,这是||&&的一个特殊属性,大多数运算符不强制执行从左到左的求值。如果左侧表达式成功,它将不会评估右侧表达式,来自C99标准草案6.5.14第4段:

与按位|运算符不同,||运算符保证从左到右的求值在第一个操作数的求值之后有一个序列点如果第一个操作数比较不等于0,则不计算第二个操作数

C++标准草案在5.15第1段中有类似的语言。

评估过程的特征与if语句完全无关。评估由表达式本身的属性决定。在if中使用它的事实没有任何区别。

在您的情况下,有问题的表达式是

charpointer == NULL || strlen ( charpointer ) == 0

它的行为主要由||运算符的属性定义,该运算符保证从左到右求值,第一个操作数的求值在第二个操作数求值之前排序,如果第一个操作量求值为true,则为"过早完成"("短路")。

这意味着你原来帖子中的控制性表达是完全安全的。

如其他人从左到右所示,评估的顺序是,但重要的是要意识到,评估停止在可以确定逻辑表达式的真值(或不真值)的点上。

||和&。

这一点尤其重要,因为您不能假设将对整个表达式进行求值,因此如果逻辑表达式的任何组件有副作用(如函数调用、增量、赋值等),则不必全部执行。

测试charpointer是否为null。

   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==NULLMUST的测试必须放在第一位,因为表达式是从左到右计算的。

最后,在你写了相当多的c代码之后,你会学到:

   if (! charpointer)  {  // etc.

与测试它是否等于NULL相同。所以,只是想写一些不可读的代码,那么:

   if (!charpointer || !(strlen(charpointer)) { // etc.

从左到右的评估顺序。

在您的情况下,if循环将从左到右检查第一个条件。如果第一个条件失败,它将从左到右检查第二个条件。