NULL是什么类型?

7

我想知道在C语言中NULL是什么类型。这可能是一个重复的问题,但是我在搜索时一直得到有关void类型的信息。也许更好的方式是,NULL是否可以作为任何类型函数的返回值?例如:

int main(){
    dosomething();
    return NULL;
}

这个可以工作吗?


1
在C语言中不存在NULL。你可能正在使用类似于#define NULL 0的东西,这应该能解决你的问题。 - SLaks
6
在C语言中,通常使用void *表示空指针,即#define NULL ((void *)0)。而在C++中,表示空指针只需使用0即可。 - Paul R
@PaulR 我可以在一个int函数中返回void吗? - Hovestar
1
int不是指针。 - Robert Harvey
为什么不直接返回零呢? - Robert Harvey
显示剩余7条评论
2个回答

14
NULL的类型可以是整数类型或void *。这是因为C标准允许它被定义为整数常量表达式或强制转换为void * 的结果。
据C 2018 7.19 3所述,当包含以下多个头文件之一时:<locale.h><stddef.h><stdio.h><stdlib.h><string.h><time.h><wchar.h>NULL“扩展为实现定义的空指针常量”。
C 6.3.2.3 3表示,空指针常量是一个“值为0的整数常量表达式,或这样的表达式转换为类型void *”。
因此,C实现可以将NULL定义为以下任何一种:
- 0,其类型为int, - ((void *) 0),其类型为void *,或者 - (1+5-6),它是一个值为0且类型为int的整数常量表达式。
即使NULL可能具有整数类型,也可以将其与指针进行比较和分配,例如:if (p == NULL) …。这些操作的规则是将整数常量零转换为适当的指针类型进行操作。
虽然NULL可能被定义为0,但它旨在用于指针,而不是作为整数零。程序应避免这样做,C实现通常最好将其定义为((void *) 0),以帮助避免可能被接受为整数值的错误。在大多数C实现中,将NULL转换为整数会产生零。然而,在C标准中并不保证这一点。允许(int)NULL(uintptr_t)NULL会产生某些特殊的“不使用”位置的地址,而不是零。即使(int)(void*)0也可能产生这样的地址,而不是零。
当将整数常量零转换为指针类型时,C实现会对其进行特殊处理;即使其空指针使用的地址不是零,它也会为该实现生成一个空指针。它是一个整数常量的事实意味着编译器可以在源代码中识别转换时应用这种特殊处理。如果我们有一些非常量表达式,例如一个int变量x,那么(void*)x不能保证产生一个空指针,即使x的值为零。

请注意,这并不保证将转换为 void * - Brave Sir Robin
stddef.h或其他标准头文件中定义了该宏。 - ouah
那么,假设我有一个函数可以检查输入s是否为空字符串,我是否可以合理地确信,假如我有strlen的访问权限,当s某种方式为NULL时,if(s && strlen(s) == 0)return true;不会返回true?或者必须首先显式检查s != NULL吗? - Blake Schwartz
如果sNULL,则s && strlen(s)的值为假,并且不会计算strlen。因此,没有必要进行预先测试。 - Eric Postpischil

2

NULL的类型是什么?

简短回答:NULL的类型是void*或者intlongunsigned等。


除了@Eric Postpischil提出的编程陷阱外,还需要补充一些内容。

(宏) NULL 扩展为一个实现定义的空指针常量。C11dr §7.19 3

一个整数常量表达式,其值为0,或将这样的表达式强制转换为类型void *,称为空指针常量。§6.3.2.3 3

NULL类型有很多可能性,给定“整数常量”。可移植的代码不应假设特定的类型。NULL最好在指针上下文中使用。

// Poor code as NULL may not match the type of the specifier - undefined behavior
printf("%p\n", NULL); // poor
printf("%d\n", NULL); // poor

// Better
printf("%d\n", (int) NULL);

// Best.  NULL is best used in a pointer context, print as a pointer
printf("%p\n", (void *) NULL);

NULL的不良使用列表中,我想要加上对字符串零终止的使用。我在Stack Overflow看到很多例子中,有人使用NULL而非0'\0'0x0等进行零终止。 - HAL9000
@HAL9000 根据需要添加。 - chux - Reinstate Monica

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