NULL是一个指针吗?

5

我之前和我的教授发生了一场争论,我辩称NULL并不是一个指针,但他坚持认为它是,因为有NULL指针这个概念。现在我有点困惑,不确定NULL到底是不是指针。

我已经在网上搜索过了,但没有找到答案,所以我的最后一个选择就是在这里求助。


那么当将NULL赋值给指针时,你认为会发生什么?它包含什么? - phuclv
1
这取决于你所说的“是指针”是什么意思。由于您标记了“概念性”,我认为您可能正在以与正式语言定义不同的方式使用术语“指针”。 - Raymond Chen
@phuclv 指针指向空或零。 - Joe
指向空的指针是一个空指针。 - phuclv
@Joe:您可以通过点击下方灰色复选标记来接受其中一个答案。 - chqrlie
这是一个C++中的整数常量,并且在POSIX中将0强制转换为(void *) - S.S. Anne
3个回答

4
在C语言中,NULL是一个宏,它会被扩展成一个空指针常量。 7.19p3

这些宏是:

NULL,它会扩展成一个实现定义的空指针常量; ...

空指针常量是一个整型常量表达式,并且其值为0(例如:01-142*0LL等),或者是这样的一个表达式强制转换成(void*)类型之后得到的结果。 6.3.2.3p3

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

大多数常见的C语言实现将NULL定义为00L((void*)0)
所以你是正确的,NULL不一定是指针。
(如果我没记错,C++甚至不允许在NULL中使用(void*)类型转换,这意味着C++中的NULL始终具有整型类型。由于C++中的void*指针与常规指针不能轻易比较,因此C++11现在具有特殊的nullptr关键字。)

@Joe 如果它有(void *)的强制转换,那么它就具有(void)指针类型。 - Petr Skocik
1
@Joe NULL是一个宏,它扩展为一个非特定值,可以与指针进行比较。NULL值可能具有void指针类型,也可能是整数。通常是00L((void*)0) - Petr Skocik
请注意,这个问题被标记为“概念性”,而不是“语言律师”,所以我的猜测是这个问题与NULL宏关系不大,而更多地涉及到“空指针”作为一个概念。 - Raymond Chen

3

NULL本身不是指针,它是一个宏,可以用来将指针初始化为其类型的空指针值。当与指针比较时,如果指针是空指针,则相等,如果指针是其类型的有效对象指针,则不相等。

char *p = 0;char *p = NULL;之间没有语义上的区别,但后者更明确,并且在其他操作数不明显是指针或与整数比较看起来像类型不匹配的情况下,使用NULL而不是0更加信息丰富:

FILE *fp = fopen("myfile", "r");
if (fp == NULL) {
    /* report the error */
}

同样,在C语言中,'\0'0之间没有语义上的区别,它们都是int常量。第一个是空字节,第二个是空值。明智地使用0'\0'NULL可能看起来徒劳无功,但可以使代码更易读,不仅能让其他程序员更容易理解,也能让自己更容易理解。

混淆可能来自于拼写错误或听错了空指针作为NULL指针。C标准经过仔细校对,只使用空指针并将NULL仅称为宏NULL

注意,然而,接受的NULL定义之一,#define NULL ((void*)0)使NULL成为指向void空指针之一。


0

关于“指向地址0的指针”的概念并没有问题。

规则是您被禁止对其进行解引用...它允许存在,如果创建将符合我能想到的“指针标准”。 仅仅因为它不是有意义地指向某个东西的指针...


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