c++NULL指针

本文详细讨论了C++中的NULL指针,包括NULL的定义、与0的关系、内存分配失败时malloc的返回值、C++11的nullptr以及NULL与空字符串、未初始化指针的区别。强调了在C++中使用0或nullptr作为空指针的推荐做法,同时提醒了函数重载时使用0可能引发的问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在C语言中,我们使用NULL表示空指针,也就是我们可以写如下代码:

int *i = NULL;
foo_t *f = NULL;

实际上在C语言中,NULL通常被定义为如下:

#define NULL ((void *)0)

        也就是说NULL实际上是一个void *的指针,然后吧void *指针赋值给int *和foo_t *的指针的时候,隐式转换成相应的类型。而如果换做一个C++编译器来编译的话是要出错的,因为C++是强类型的,void *是不能隐式转换成其他指针类型的,所以通常情况下,编译器提供的头文件会这样定义NULL:

#ifdef __cplusplus ---简称:cpp c++ 文件
#define NULL 0
#else
#define NULL ((void *)0)
#endif

证明int *p=NULL

例1:

int*p = NULL;
// int *p = 0;
 if (p)
 {
  cout << "不是NULL"<<endl;
 }
 else
 {
  cout << "是NULL" << endl;
 }
 return 0;

}

打印结果:


例2

NULL指针的地址为:

int *p;

p=NULL;

cout<<p<<endl;
打印结果:


例3 

int *p;
 int *p1;
 int *p2;
 int *p3;
 p = 0;
 p1 = '\0';
 p2 = 3 - 3;
 p3 = NULL;
 cout << "0: " << p << endl;
 cout << "\\0:  " << p1 <<endl;
 cout << "3-3: " << p2 << endl;
 cout << "NULL: " << p3 << endl;
 return 0;
打印结果:

1.memset(&p,0,sizeof(p));和p=0;是等价的吗?

       答案是否定的,虽然在大多数系统上是等价的,但是因为有的系统存在着“非零空指针” (nonzero null pointer),所以这时两者不等价。由于这个原因,要注意当想将指针设置为空指针的时候不应该使用 memset,而应该用空指针常量或空指针对指针变量赋值或者初始化的方法。

NULL 是标准库中的一个符合上述条件的 reserved identifier (保留标识符)。所以,如果包含了相应的标准头文件而引入了 NULL 的话,则再在程序中重新定义 NULL 为不同的内容是非法的,其行为是未定义的。也就是说,如果是符合标准的程序,其 NULL 的值只能是 0,不可能是除 0 之外的其它值,比如 1、2、3 等。

 

2.malloc 函数在分配内存失败时返回 0 还是 NULL?

 malloc 函数是标准 C 规定的库函数。在标准中明确规定了在其内存分配失败时返回的是一个 “null pointer”(空指针):

[7.20.3-1] If the space cannot be allocated, a null pointer is returned.

          对于空指针值,一般的文档(比如 man)中倾向于用 NULL 表示,而没有直接说成 0。但是我们应该清楚:对于指针类型来说,返回 NULL 和 返回 0 是完全等价的,因为 NULL 和 0 都表示 “null pointer”(空指针)。(tyc:一般系统中手册中都返回NULL,那我们就用NULL吧

3.最好用0代表空指针:

Int *p=0 和int *p=NULL一样的,最好用0,以免容易发生错误。

 

因为C++中不能将void *类型的指针隐式转换成其他指针类型,而又为了解决空指针的问题,所以C++中引入0来表示空指针(注:0表示,还是有缺陷不完美),这样就有了类似上面的代码来定义NULL。


NULL是头文件<iostream.h>(和另外几个标准库头文件)中定义的符号化常量。将指针初始化为NULL等于将指针初始化为0,但C++中优先选择0。指定0时,它变为指针的相应类型。数值0是惟一可以不将整数转换为指针类型而直接赋给指针变量的整数值。

注意:关于函数重载问题,可能使用0也会出错,虽然编译通过。

例如(a=1,b=0或者b=NULL):

foo.h

void fun(int a,int b);

void fun(int a,int *b);

a.cpp

fun(1,0);

b.cpp

fun(1,0)

如果使用了b=0(NULL没有在头文件定义时),b.cpp就不知道调用哪个函数了。使用慎重。

修改代码按照预期运行:

fun(1,static_cast<int *>(0));

C++ 11的nullptr

虽然上面我们说明了0比NULL可以让我们更加警觉,但是我们并没有避免这个问题。这个时候C++ 11的nullptr就很好的解决了这个问题,我们在C++ 11中使用nullptr来表示空指针,这样最早的代码是这样的:

b.h

fun(1,nullptr);

4.字符串'\0'和空字符串的区别(NULL):
NULL字符串是空字符串,不包含任何字符.

如果NULL没有定义在标准的C头文件中。它等于字符’\0,其值等于十进制0。

5.Null指针和未初始化的指针区别:
(1).一个指针可以被声明为void类型,比如void *x。一个指针可以被赋值为NULL。

(2).一个指针变量声明之后但没有被赋值,叫做未初始化指针。

1.未初始化的指针可能包含任何值.
2.包含null指针不会引用内存中的任何地址。
注意:不应该对null指针进行解引,因为他并不包含合法地址.


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值