!var 和 var != NULL 是一样的吗?

3

我想知道在varchar *类型时,!var是否等同于var != NULL

这里有一个非常简单的 POC 证明它们不是相同的(或者是我做错了什么?)但我不理解为什么。

int main(void) {
    char *c = NULL;
    if(!c){
        printf("1\n");
    }else{
        printf("2\n");
    }

    if(c != NULL){
        printf("1\n");
    }else{
        printf("2\n");
    }
    return 0;
}

输出结果为:
1
2

我正在运行这个程序在x64 Arch Linux上,GCC版本为4.8.2。
编辑:要么我需要一些真正的睡眠,要么你们都误读了程序的实际输出!请多读几次。 !c意味着“如果c不为NULL”,那么它应该在第一个if中打印2,但它却打印了1
编辑:确实,我需要一些睡眠。我不知道我在想什么。谢谢大家!

当C语言需要表达式的布尔值时,如果表达式等于零,则推断为假值;否则为真值。这基本上是c89 / c90的措辞。(c89仍具有隐藏布尔构造) - wildplasser
6个回答

5

!var 相当于 var==NULL

因此,您的第一个测试检查 if (var == NULL)。 您的第二个测试检查相反的结果,因此给出了相反的结果。

逻辑非运算符 ! 的这种行为在 C11 6.5.3.3 一元算术运算符 p5 中有描述:

逻辑非运算符的结果是0,如果它的操作数的值与0不相等,则为1,如果它的操作数的值与0相等,则为1。


1
@alexandernst:不,它检查的是c是否与NULL相同 - Oliver Charlesworth
这并不完全正确。指针是不同的。NULL 不必被表示为全零,因此 (!p) 和 (p != NULL) 都有点特殊(因为 p 是指针类型)。当需要布尔结果时,p 被评估为指针表达式。 - wildplasser
1
@wildplasser:我不确定你的观点是什么——语言规范是这样的,即!p等同于0==p。如果p是一个指针,那么等式中的0就是空指针常量。 - Michael Burr
1
不是这样。NULL 不需要是 0。NULL 相当于 (void*) 0。某些架构(比如 AIX)可能会选择与全零不同的表示方法来表示 NULL 指针。(p == NULL) 是独立于体系结构的,(!p) 也是如此。而且:它们是等价的。 - wildplasser
1
@wildplasser:虽然空指针在硬件层面上不需要是零位,但在'C'语言层面上,0代表空指针(无论它在硬件层面上如何表示)。 - Michael Burr
显示剩余4条评论

2
我想知道如果var是char *,!var是否等同于var != NULL。
如果var是声明为对象指针类型(例如char *),则!var等同于var == NULL。

2
表达式 !varvar为假时为真,而在C语言中,当var0相等时,var为假。

在指针上下文中使用时,NULL相当于0

因此,!var等价于var == NULL


1

!varvar == NULL相同,而不是!=。在这种情况下,你的测试有缺陷 - if(c != NULL){将与if (c) {相同,而不是if(!c){

然而,NULL是一种可恶的东西 - 它通常通过宏定义处理,因此NULL在你的环境中可能有完全不同的含义,这可能会使你的代码(如果按照你的意图编写)仍然显示你所描述的内容。


1

char *c = NULL 将指针 c 初始化为 NULL

if(!c) 等同于 if(!0),结果为真。

if(c != NULL) 等同于 if(c != 0),结果为假。


1

(!c)(c != NULL)是两个相反的条件(如果一个为真,则另一个为假)。

(!c)等同于"if(c == 0)"或"if(c == NULL)",因为c初始化为NULL,所以为真。 (c != NULL)等同于"if(c!=0)",因为c等于NULL,所以为假。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接