C中的NULL是否需要/定义为零?

wil*_*lhf 49 c null

在我的GCC测试程序中,NULL似乎为零,但维基百科说NULL只需指向无法寻址的内存.

有没有编译器NULL非零?我很好奇是否if (ptr == NULL) 更好的做法if (!ptr).

Mat*_*lia 63

NULL保证为零,也许保证为(void *)1.

C99,§6.3.2.3,3

带有值的整型常量表达式0或类型转换为类型的表达式 void *称为空指针常量.(55)如果将空指针常量转换为指针类型,则保证结果指针(称为空指针)比较不等于指向任何对象或函数的指针.

注55说:

55)宏NULL在<stddef.h>(和其他头部)中定义为空指针常量.

请注意,由于如何制定空指针的规则,用于分配/比较空指针的值保证为零,但实际存储在指针内的位模式可以是任何其他东西(但AFAIK只有少数很多)深奥的平台利用了这个事实,这不应该是一个问题,因为要"看到"你应该进入UB -land 的基础位模式无论如何).


因此,就标准而言,这两种形式是等价的(!ptr等同于ptr==0§6.5.3.35,ptr==0相当于ptr==NULL); if(!ptr)也是非常惯用的.

话虽如此,我通常会明确地编写,if(ptr==NULL)而不是if(!ptr)更清楚地表明我正在检查指针是否为null而不是某些布尔值.


  1. 请注意,在C++ void *中,由于更严格的隐式转换规则会导致使用这种NULL繁琐(您必须每次都明确地将其转换为比较指针的类型),因此无法使用强制转换.

  • 最重要的一点:'void*p; memset(&p,0,sizeof p);`不使`p` a*NULL*指针. (9认同)
  • 但是,空指针中的字节不需要为零. (7认同)
  • @aschepler:我在答案中写了什么? (4认同)
  • @SimonRichter:它不一定*使`p`为空指针.(它很可能在大多数系统上运行,但取决于它会使您的代码不可移植.) (3认同)

Joh*_*ode 11

从语言标准来看:

6.3.2.3指针
...
3值为0的整型常量表达式,或者这种表达式转换为类型 void *,称为空指针常量.55)如果将空指针常量转换为指针类型,则保证将结果指针(称为空指针)与指向任何对象或函数的指针进行比较.
...
55)宏NULL<stddef.h>(和其他标题)中定义为空指针常量; 见7.17.

给定该语言,宏NULL 应该计算为零值表达式(未修饰的文字0,类似表达式(void *) 0,或最终计算结果为0的另一个宏或表达式).表达ptr == NULL!ptr应该是等价的.第二种形式往往是更惯用的C代码.

请注意,空指针不必为0.底层实现可以使用它想要表示空指针的任何值.但是,就源代码而言,零值指针表达式表示空指针.