比较中NULL与零的区别

时间:2016-01-11 16:02:42

标签: c++ c null nullptr

我对NULL有一点了解,但是当我们进行比较时,我感到很困惑。例如:

int* p;
if(p == NULL){
//do sth
}
if(p == 0){
//do sth
}

在第一次比较中“p”与什么地址相比较? 它是否寻找“p”的参考点?(并查看它是否有效)

6 个答案:

答案 0 :(得分:3)

来自C99标准:

  

7.17常见定义<stddef.h>

     

3宏是

NULL
     

扩展为实现定义的空指针常量; ...

来自C ++ 11标准:

  

18.2类型

     

3宏NULL是本国际标准(4.10)中实现定义的C ++空指针常量。 194

脚注194:

  

194)可能的定义包括00L,但不包括(void*)0

Microsoft VS 2008将其定义为:

/* Define NULL pointer value */
#ifndef NULL
#ifdef __cplusplus
#define NULL    0
#else
#define NULL    ((void *)0)
#endif
#endif

gcc / g ++ 4.9.3将其定义为:

#if defined (_STDDEF_H) || defined (__need_NULL)
#undef NULL     /* in case <stdio.h> has defined it. */
#ifdef __GNUG__
#define NULL __null
#else   /* G++ */
#ifndef __cplusplus
#define NULL ((void *)0)
#else   /* C++ */
#define NULL 0
#endif  /* C++ */
#endif  /* G++ */
#endif  /* NULL not defined and <stddef.h> or need NULL.  */

我怀疑其他现代编译器的定义类似。

鉴于NULL的上述定义,行

if(p == NULL){

扩展为:

if(p == ((void*)0) ){

在C。

它扩展到

if(p == 0){

在C ++中。

在其他C ++编译器中,该行可以扩展为

if(p == 0L){

使用C ++ 11时,最好避免NULL并开始使用nullptr

if ( p == nullptr ) {

答案 1 :(得分:3)

从概念上讲,NULL是一个指向无处的奇异指针值,可以隐式转换为任何指针类型。
实际上,除非您在仅指针的上下文中使用它,否则您不能依赖它作为指针值。

因此,在C ++ 11及更高版本中分别使用nullptr 0转换为右指针类型,尤其是在整数零不会转换为指针的上下文中。

BTW:在大多数现代系统中,空指针实际上是全位 - 零,标准不需要(可能有许多位模式表示空指针,没有全零),并且对源代码中如何表示空指针常量没有任何区别。

在C ++中:

  

NULL是本国际标准(4.10)中实现定义的C ++空指针常量。

定义为:

  

空指针常量是整数文字(2.14.2),其值为零或prvalue类型为std::nullptr_t

Pre-C ++ 11最后一个选项显然不可用...
而且在C ++ 11之后,因为你不知道它是什么,你应该直接使用nullptr

在C:

  

宏是   NULL   它扩展为实现定义的空指针常量; ...

定义为:

  

值为0的整型常量表达式,或者类型为void *的表达式,称为空指针常量。

答案 2 :(得分:2)

在C的每个现代实现中,NULL为零,通常作为指针值:

#define  NULL  (void *) 0

因此,比较一个字符到NULL可能是无效的:

char ch = 'a';
if (ch == NULL)     //  probably "invalid comparison of pointer with scalar"

作为指针值,选择NULL以指向无效内存,以便取消引用它(在适当的体系结构上)将导致内存故障。大多数虚拟机仅为此目的保留较低内存,并通过将未映射的低内存留给物理内存来实现。没有保留多少内存?可能是几千字节,但许多实现保留几兆字节。

答案 3 :(得分:1)

C ++编译器中的

NULL只是一个定义“空指针常量”(通常为0的值)的宏。所以除了NULL用于表示意图(这很重要)之外没有区别。例如,您可以使用值int创建一个NULL变量,该变量未对标准声明(int a = 0;)进行任何特殊处理。

NULL NOT “内存中的空白区域”。它只是一个符号(通常)表示缺少某些东西(值,指针等......)。

但是现在不鼓励在C ++中使用NULL,而应该使用更优越的 .isFromMockProvider()

答案 4 :(得分:1)

NULL表示任何有效指针都不使用的值。因此,如果指针为NULL,则它指向根本没有变量。在指针上下文中,值零意味着与NULL相同,但使用NULL而不是零更清楚。这就是你需要知道的关于NULL的一切。

答案 5 :(得分:1)

  

知道NULL是内存中的空白区域

不完全 - NULL是一个明确定义的“无处”,与任何有效的内存地址都不对应。

在C和C ++中,NULL宏被定义为空指针常量,它是一个零值整数表达式。 C ++还提供nullptr文字,它也会计算空指针常量。当空指针常量出现在指针上下文中时,它将转换为实现定义的空指针。空指针值可能是也可能不是0值,但保证比较不等于任何有效指针值。

C 2011 online standard

6.3.2.3指针
...
3一个整数常量表达式,其值为0,或者此类表达式强制转换为类型 void * ,称为空指针常量 66)如果将空指针常量转换为a 指针类型,结果指针,称为空指针,保证比较不等 指向任何对象或函数的指针。 66))宏NULL<stddef.h>(和其他标题)中定义为空指针常量;见7.19

C++ 2014 online draft

2.13.7指针文字[lex.nullptr]
指针字面
nullptr

1指针文字是关键字nullptr。它是std::nullptr_t类型的prvalue。 [注意std::nullptr_t 是一种不同的类型,既不是指针类型也不是指向成员类型的指针;相反,这种类型的prvalue是 空指针常量,可以转换为空指针值或空成员指针值。见4.10 和4.11。 - 结束记录]

4.10指针转换[conv.ptr]
1 空指针常量是一个整数文字(2.13.2),其值为零或prvalue类型为std::nullptr_t。 空指针常量可以转换为指针类型;结果是该类型的空指针值 并且可以与对象指针或函数指针类型的每个其他值区分开。这样的转换 被称为空指针转换。相同类型的两个空指针值应相等。该 将空指针常量转换为指向cv限定类型的指针是单个转换,而不是 指针转换的序列,然后是限定转换(4.4)。空指针常量 整数类型可以转换为std::nullptr_t类型的prvalue。 [注意:结果prvalue不是 空指针值。 - 结束记录]
...
18.2类型[support.types]
...
3宏NULL是本国际标准中实现定义的C ++空指针常量 (4.10)。 194 194)可能的定义包括0和0L,但不包括(void *)0

要点回家的一些观点:

  1. NULL宏,nullptr文字(仅限C ++)和空指针常量始终为0值;
  2. 空指针不必是0值;
  3. 空指针永远不会等于有效的内存地址;
  4. 编译器的工作是将源代码中的空指针常量映射到生成的机器代码中的等效空指针 value ;作为程序员,您(通常)不需要担心实现中的实际空指针;
  5. 由于空指针常量始终为0值,因此将指针值与0进行比较应相当于将其与NULLnullptr进行比较。