为什么有时会对一个字符串进行两次检查?
Why do you sometimes do two checks on a string?
我看到了这段代码:
char *str;
// Some code
if (! str || ! *str)
return str;
为什么要检查! *str
?if (! str)
还不够吗?
这取决于您要检查的内容:
!str
检查 str 是否为 NULL。
!*str
检查 str
中的第一个字符是否为 NUL 字节 ('\0')
合并后,如果 s 为 NULL,或者 s 指向 NUL 字符,它们将 return 's'
来看一个道理table:
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
是一个 NULL 指针,那么 !str
将为真,并且总是返回 str
。如果 str
不是 NULL 指针,则仅当 *str
是 NUL 终止符时才会返回 str
。
请注意,您可以使用布尔代数将其重写为!(str && *str)
。括号用英文可以表示为"non-empty string"。所以整个条件是 "not non-empty string".
请注意,它之所以起作用是因为 短路 这意味着如果 ||
或 &&
的结果只能由左操作数确定,则不会计算右操作数。否则,当 str
是 NULL 指针时,取消引用将产生未定义的行为。
在这里,有一个非常重要的逻辑问题需要注意。仅仅因为一个字符串不是 "not empty" 并不一定意味着它是空的。但这在一定程度上取决于解释。共有三种情况,这里是所有情况的示例。
"Hello, World[=21=]"
- 绝对不为空
"[=22=]"
- 肯定是空的
NULL
- 绝对不是"not empty",但它是空的吗?
我可能会补充说,这是返回 str
的一个非常奇怪的条件。这不是你通常会做的事情。
我看到了这段代码:
char *str;
// Some code
if (! str || ! *str)
return str;
为什么要检查! *str
?if (! str)
还不够吗?
这取决于您要检查的内容:
!str
检查 str 是否为 NULL。!*str
检查str
中的第一个字符是否为 NUL 字节 ('\0')
合并后,如果 s 为 NULL,或者 s 指向 NUL 字符,它们将 return 's'
来看一个道理table:
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
是一个 NULL 指针,那么 !str
将为真,并且总是返回 str
。如果 str
不是 NULL 指针,则仅当 *str
是 NUL 终止符时才会返回 str
。
请注意,您可以使用布尔代数将其重写为!(str && *str)
。括号用英文可以表示为"non-empty string"。所以整个条件是 "not non-empty string".
请注意,它之所以起作用是因为 短路 这意味着如果 ||
或 &&
的结果只能由左操作数确定,则不会计算右操作数。否则,当 str
是 NULL 指针时,取消引用将产生未定义的行为。
在这里,有一个非常重要的逻辑问题需要注意。仅仅因为一个字符串不是 "not empty" 并不一定意味着它是空的。但这在一定程度上取决于解释。共有三种情况,这里是所有情况的示例。
"Hello, World[=21=]"
- 绝对不为空"[=22=]"
- 肯定是空的NULL
- 绝对不是"not empty",但它是空的吗?
我可能会补充说,这是返回 str
的一个非常奇怪的条件。这不是你通常会做的事情。