我想知道 C 中的 Null 是什么类型。这可能是重复的,但我不断在搜索中获取有关无效类型的信息。也许更好的方法是可以为任何类型的函数返回 NULL?例如:
int main(){
dosomething();
return NULL;
}
这行得通吗?
NULL
的类型可以是整数类型,也可以是void *
。这是因为 C 标准允许将其定义为整数常量表达式或转换为void *
的结果。
C 2018 7.19 3 表示NULL
"扩展到实现定义的空指针常量"(当包含以下几个标头中的任何一个时:<locale.h>
、<stddef.h>
、<stdio.h>
、<stdlib.h>
、<string.h>
、<time.h>
或<wchar.h>
)。
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 实现会特别处理它;即使其 null 指针使用零以外的地址,它也会为该实现生成一个 null 指针。它是一个整数常量的事实意味着编译器可以在识别源代码中的转换时应用这种特殊处理。如果我们有一些非常量表达式,例如int
变量x
,那么即使x
的值为零,也不能保证(void *) x
产生空指针。
什么类型是空?
简短回答:NULL
的类型是void*
或int
,long
,unsigned
,...
除了@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("%pn", NULL); // poor
printf("%dn", NULL); // poor
// Better
printf("%dn", (int) NULL);
// Best. NULL is best used in a pointer context, print as a pointer
printf("%pn", (void *) NULL);