在C和C++中,NULL/false代表的不仅仅是0x0 / 0b0 / '\0' / 0。

24 浏览
0 Comments

在C和C++中,NULL/false代表的不仅仅是0x0 / 0b0 / '\0' / 0。

正如问题中提到的那样,我一直将NULL和false(在C++中)与0或0x0等互换使用。我很好奇它们是否除了作为0的同义词外还有其他特殊含义。

0
0 Comments

在C和C++中,NULL表示一个空指针。一个被声明为NULL的指针不能被引用,只能被赋予其他值。而0或者0x0可以是一个指针的值,既可以被引用也可以被赋值。

为什么会出现NULL和0的区别呢?这是因为在C和C++中,NULL被定义为0,但它的含义更为广泛。NULL不仅仅表示0,还表示一个指针指向的地址不存在或者未初始化。因此,当一个指针被赋值为NULL时,我们可以确定它没有有效的地址。

然而,0或者0x0可以是一个指针的合法值,表示指针指向的是一个有效的地址。这意味着我们可以对这样的指针进行引用和赋值操作。

那么如何解决这个问题呢?当我们需要判断一个指针是否为空时,应该使用NULL而不是0。因为NULL更准确地表示一个指针没有有效的地址。另外,在进行指针的比较操作时,也应该使用NULL而不是0,以避免歧义。

总结起来,NULL表示一个空指针,表示一个指针没有有效的地址;而0或者0x0可以是一个指针的值,表示指针指向的是一个有效的地址。为了正确地判断一个指针是否为空,以及避免歧义,我们应该使用NULL而不是0。

0
0 Comments

在C和C++中,NULL被保证为零,可能被转换为(void *)1

根据C99,§6.3.2.3, ¶3规定:

整数常量表达式的值为0,或者将这样的表达式转换为类型void *,被称为空指针常量。如果将空指针常量转换为指针类型,得到的指针称为空指针,保证与任何对象或函数的指针比较不相等。

注意到,因为空指针的规则如何制定,您用于赋值/比较空指针的值保证为零,但实际存储在指针内部的位模式可以是任何其他值(但据我所知,只有少数非常奇特的平台利用了这一事实,而且这应该不是一个问题,因为要"看到"底层位模式,您应该进入未定义行为的领域)。

因此,就标准而言,这两种形式是等价的(由于§6.5.3.3 ¶5,!ptr等效于ptr==0,ptr==0等效于ptr==NULL);if(!ptr)也是相当惯用的写法。

话虽如此,我通常会明确地写成if(ptr==NULL)而不是if(!ptr),以便更清楚地检查指针是否为空,而不是某个布尔值。

需要注意的是,在C++中,由于更严格的隐式转换规则,不能出现void *转换的情况,否则使用这样的NULL会很麻烦(每次都必须显式将其转换为比较指针的类型)。

您可以通过使用char*查看指针并读取其字节来查看底层位。然而,这些字节和位的含义是完全未指定的。

0
0 Comments

在C和C++中,NULL/false的值并不一定是0x0、0b0、'\0'或者0。这是由于不同的平台可能有不同的定义。以下是一些非零NULL值的例子。

虽然空指针的地址可能不是数值0,但是数值为0的整数常量仍然会被转换为空指针。

出现这个问题的原因是,不同的平台对于空指针的定义可能不同,导致NULL/false的值并非一定是0x0、0b0、'\0'或者0。

解决这个问题的方法是,不要通过比较NULL/false的数值来判断空指针,而应该使用特定的空指针判断语法。例如,在C中可以使用if(ptr == NULL)来判断指针是否为空,在C++中可以使用if(ptr == nullptr)来判断指针是否为空。

以下是一些示例代码,展示了如何正确地判断空指针:

#include 
int main() {
    int* ptr = NULL;
    if (ptr == NULL) {
        printf("ptr is a null pointer\n");
    } else {
        printf("ptr is not a null pointer\n");
    }
    return 0;
}

#include 
int main() {
    int* ptr = nullptr;
    if (ptr == nullptr) {
        std::cout << "ptr is a null pointer" << std::endl;
    } else {
        std::cout << "ptr is not a null pointer" << std::endl;
    }
    return 0;
}

通过使用特定的空指针判断语法,我们可以确保在不同的平台上都能正确地判断空指针。这样可以避免因为NULL/false的值不是0而导致的错误判断。

0