2

我在程序开始时有一个 char 指针初始化为 NULL,在程序中,char* 用于函数调用,它可能指向一个 char 字符串,它可能指向 null char,它可能保持不变。下面的陈述是否正确,如果表达式是从左到右计算的,应该是正确的。如果不是,则strlen ( charpointer )是未定义的行为,如果charpointer == NULL

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

那么,他们是否从左到右进行评估?这是进行这样检查的正确方法吗?

4

5 回答 5

11

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

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

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

于 2013-08-26T18:30:53.997 回答
4

if评价过程的特点与陈述绝对无关。评估由表达式本身的属性决定。使用它的事实if没有任何区别。

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

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

它的行为主要由||operator 的属性定义,它保证从左到右进行评估,第一个操作数的评估在第二个操作数的评估之前进行排序,并且“过早完成”(“短路”)以防万一第一个操作数的计算结果为true

这意味着您原始帖子中的控制表达式是完全安全的。

于 2013-08-26T19:04:46.160 回答
2

正如其他人从左到右所指出的那样,评估的顺序是重要的,但重要的是要认识到评估停止在可以确定逻辑表达式的真值(或缺乏真值)的点上。

这两种情况都是|| 和 &&。

这一点特别重要,因为您不能假设将评估整个表达式,因此如果逻辑表达式的任何组件具有副作用(例如函数调用、增量、赋值等),它们不一定都是执行。

于 2013-08-26T18:56:31.040 回答
2

测试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.
于 2013-08-26T19:00:06.323 回答
0

评价顺序从左到右。

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

于 2013-08-26T18:32:58.687 回答