我正在观看一个示例,看到了以下内容:
char *str;
/* ... */
if (!str || !*str) {
return str;
}
这是什么意思?是空的还是其他什么情况?
str
是一个char指针。 !
对其取反。基本上,当str == NULL
时,!str
将评估为true(1)。
第二部分的意思是,(如果str
指向某些东西),则在第一个字符是空字符('\0'
)时评估为true(1)-这意味着它是一个空字符串。
注意:
*str
解除引用指针并检索第一个字符。这与执行str [0]
相同。
!
将其转换为布尔值,然后取反该布尔值。 - Potatoswatterstr == NULL
,而不是 *str == NULL
。而且 *str
是一个字符,不是一个指针。 - M.Mstr
是一个char指针,*str
是一个char。 - M.M*str
并不意味着解引用指针,而是char *str
。我表达不清楚。 - pushkin!
返回1
,否则返回0
。结果的类型为int
。 - Keith Thompson!str
的意思是字符串str
没有分配内存。 !*str
的意思是str
指向一个空字符串。
str
将导致未定义行为,因此!str
无意义。 换句话说,如果在没有触发UB的情况下评估!str
,则等效于测试str
是否指向分配的内存(或超出末尾)。 - M.Mfree
实现为类似函数宏的形式(§7.1.4),该宏将其参数分配为 NULL
,利用该值是不确定的这种特性。(这将需要一些魔法来区分左值,但它将符合规范。)我的断言将不会触发。 - Potatoswatter!str
的值为 true 表示没有内存分配给 str
"。我们指出了一个注意事项(你的答案可能需要提到),如果 str
是一个悬空指针(因此不指向已分配的内存),那么 !str
会导致未定义行为;因此程序可能表现为 !str
的值为 true。 - M.M在提问之前,您可以进行小型测试。
#include <stdio.h>
int main()
{
char *str = "test";
printf("%d\n",*str);
printf("%c\n",*str); // str[0]
printf("%d\n",str);
if (!str || !*str)
{
printf("%s",str);
}
return 0;
}
!
的意思是否定。 if
条件语句中除了 0
以外的所有值都为真。在这里,str
和 *str
返回的值不是 0
。因此,你可以得出一个推论。
第一个表达式!str
的计算结果为真,如果str
设置为NULL
,如果设置为其他任何值,则为假无论指向的内存是否仍被分配。 如果str
保留为不再活动的内存,则这可能导致未定义的行为。
第二个表达式!*str
在!str
由于布尔或运算符的短路作用而计算为真时,只有在str
中地址处的值为\0
(空字符)时才为真,但根本不会被计算。
!x
等价于x == 0
,始终如一。 - M.Mchar* segfault_maybe(void)
。 - geometrianchar *str;
来展示str
的原始定义,在“真实代码”中有一些其他的东西。 - M.Mchar* str = /*something*/;
这样的代码来防止像我这样的吹毛求疵的人。 - geometrian