C 为什么有时对一个字符串进行两次检查?

C 为什么有时对一个字符串进行两次检查?,c,null-pointer,C,Null Pointer,我看到了这个代码: char *str; // Some code if (! str || ! *str) return str; 为什么需要检查*str?如果(!str)足够,是否不够?这取决于您要检查的内容: !str检查str是否为空 *str检查str中的第一个字符是否为NUL字节(“\0”) 如果s为NULL,它们组合起来将返回“s”,或者s指向NUL char,这取决于您要检查的内容: !str检查str是否为空 *str检查str中的第一个字符是否为NUL字节(“

我看到了这个代码:

char *str;
// Some code
if (! str || ! *str)
    return str;

为什么需要检查
*str
?如果(!str)足够,是否
不够?

这取决于您要检查的内容:

  • !str
    检查str是否为空
  • *str
    检查
    str
    中的第一个字符是否为NUL字节(“\0”)

如果s为NULL,它们组合起来将返回“s”,或者s指向NUL char,这取决于您要检查的内容:

  • !str
    检查str是否为空
  • *str
    检查
    str
    中的第一个字符是否为NUL字节(“\0”)

如果s为NULL,它们组合在一起将返回's',或者s指向NUL char

让我们看看真值表:

str    *str    !str   !*str   !str || !*str
T      T       F      F       F
F      T       T      F       T
T      F       F      T       T
F      F       T      T       T
因此,如果
str
是空指针,那么
!str
将为true,并且始终返回
str
。如果
str
不是空指针,则仅当
*str
是NUL终止符时才会返回
str

请注意,您可以使用布尔代数将其重写为
!(str&&str)
。括号可以用英语表示为“非空字符串”。所以整个条件是“非空字符串”

请注意,它之所以能工作是因为短路,这意味着如果只能由左操作数确定
|
&&
的结果,则不会计算右操作数。否则,当
str
为空指针时,取消引用将产生未定义的行为

这里有一个非常重要的逻辑问题需要注意。仅仅因为字符串不是“非空”并不一定意味着它是空的。但这在一定程度上取决于解释。有三种情况,下面是所有这些情况的一个例子

  • “你好,世界\0”
    -绝对不是空的
  • “\0”
    -绝对为空
  • NULL
    -肯定不是“不空”,但它是空的吗

我可以补充一点,对于返回
str
,这是一个非常奇怪的条件。这不是你通常会做的事情。

让我们看看真相表:

str    *str    !str   !*str   !str || !*str
T      T       F      F       F
F      T       T      F       T
T      F       F      T       T
F      F       T      T       T
因此,如果
str
是空指针,那么
!str
将为true,并且始终返回
str
。如果
str
不是空指针,则仅当
*str
是NUL终止符时才会返回
str

请注意,您可以使用布尔代数将其重写为
!(str&&str)
。括号可以用英语表示为“非空字符串”。所以整个条件是“非空字符串”

请注意,它之所以能工作是因为短路,这意味着如果只能由左操作数确定
|
&&
的结果,则不会计算右操作数。否则,当
str
为空指针时,取消引用将产生未定义的行为

这里有一个非常重要的逻辑问题需要注意。仅仅因为字符串不是“非空”并不一定意味着它是空的。但这在一定程度上取决于解释。有三种情况,下面是所有这些情况的一个例子

  • “你好,世界\0”
    -绝对不是空的
  • “\0”
    -绝对为空
  • NULL
    -肯定不是“不空”,但它是空的吗


我可以补充一点,对于返回
str
,这是一个非常奇怪的条件。这不是你通常会做的。

str
字符指针吗?这取决于它应该测试什么。考虑<代码> char STR[] =“”;
@k99“为什么需要检查!*str?”您不需要!:)而且你甚至不需要检查!str!:)例如,标准C字符串函数不这样做。:)我们不知道为什么,甚至不知道您是否需要检查它,因为您没有提供上下文。您需要提供更多的上下文信息。。你有350个名声,所以你应该知道。
str
是字符指针吗?这取决于它应该测试什么。考虑<代码> char STR[] =“”;
@k99“为什么需要检查!*str?”您不需要!:)而且你甚至不需要检查!str!:)例如,标准C字符串函数不这样做。:)我们不知道为什么,甚至不知道您是否需要检查它,因为您没有提供上下文。您需要提供更多的上下文信息。。您有350个声誉,所以您应该知道。问题中指定的函数检查“isEmpty”。@dash-o Ehm,否?问题中的代码片段不会返回
bool
。如果
str[0]==0
@Gerhardh-Ehm,它也不会返回
NULL
,是吗?我说我重写了它。问题的核心是实际的检查。@k99根据定义,字符串以NUL终止符结尾。后面没有任何内容。如问题中所述,该函数将检查“isEmpty”。@dash-o Ehm,否?问题中的代码段不会返回
bool
。如果
str[0]==0
@Gerhardh-Ehm,它也不会返回
NULL
,是吗?我说我重写了它。问题的核心是实际的检查。@k99根据定义,字符串以NUL终止符结尾。之后什么也没有了。