首页 > 编程语言 >c++ NULL nullptr 区别

c++ NULL nullptr 区别

时间:2024-05-31 11:35:25浏览次数:18  
标签:void nullptr C++ c++ 类型 NULL 指针

 

C++中NULL和nullptr的区别

在编写C程序的时候只看到过NULL,而在C++的编程中,我们可以看到NULL和nullptr两种关键字,其实nullptr是C++11版本中新加入的,它的出现是为了解决NULL表示空指针在C++中具有二义性的问题,为了弄明白这个问题,我查找了一些资料,总结如下。

一、C程序中的NULL

在C语言中,NULL通常被定义为:#define NULL ((void *)0)

所以说NULL实际上是一个空指针,如果在C语言中写入以下代码,编译是没有问题的,因为在C语言中把空指针赋给int和char指针的时候,发生了隐式类型转换,把void指针转换成了相应类型的指针。

int  *pi = NULL;
char *pc = NULL;

二、C++程序中的NULL

但是问题来了,以上代码如果使用C++编译器来编译则是会出错的,因为C++是强类型语言,void*是不能隐式转换成其他类型的指针的,所以实际上编译器提供的头文件做了相应的处理:

#ifdef __cplusplus
#define NULL 0
#else
#define NULL ((void *)0)
#endif

可见,在C++中,NULL实际上是0.因为C++中不能把void*类型的指针隐式转换成其他类型的指针,所以为了结果空指针的表示问题,C++引入了0来表示空指针,这样就有了上述代码中的NULL宏定义。

但是实际上,用NULL代替0表示空指针在函数重载时会出现问题,程序执行的结果会与我们的想法不同,举例如下:

复制代码
#include <iostream>
using namespace std;
 
void func(void* i)
{
    cout << "func1" << endl;
}
 
void func(int i)
{
    cout << "func2" << endl;
}
 
void main(int argc,char* argv[])
{
    func(NULL);
    func(nullptr);
    getchar();
}
复制代码

  

在这段代码中,我们对函数func进行可重载,参数分别是void*类型和int类型,但是运行结果却与我们使用NULL的初衷是相违背的,因为我们本来是想用NULL来代替空指针,但是在将NULL输入到函数中时,它却选择了int形参这个函数版本,所以是有问题的,这就是用NULL代替空指针在C++程序中的二义性。

三、C++中的nullptr

为解决NULL代指空指针存在的二义性问题,在C++11版本(2011年发布)中特意引入了nullptr这一新的关键字来代指空指针,从上面的例子中我们可以看到,使用nullptr作为实参,确实选择了正确的以void*作为形参的函数版本。

总结:

NULL在C++中就是0,这是因为在C++中void* 类型是不允许隐式转换成其他类型的,所以之前C++中用0来代表空指针,但是在重载整形的情况下,会出现上述的问题。所以,C++11加入了nullptr,可以保证在任何情况下都代表空指针,而不会出现上述的情况,因此,建议以后还是都用nullptr替代NULL吧,而NULL就当做0使用。

其他:在没有C++ 11的nullptr的时候,我们怎么解决避免这个问题呢?

复制代码
const class nullptr_t
{
public:
    template<class T>
    inline operator T*() const
        { return 0; }
 
    template<class C, class T>
    inline operator T C::*() const
        { return 0; }
 
private:
void operator&() const;
} nullptr = {};
复制代码

转自:https://blog.csdn.net/qq_18108083/article/details/84346655

标签:void,nullptr,C++,c++,类型,NULL,指针
From: https://www.cnblogs.com/rebrobot/p/18224144

相关文章

  • 深入理解 C++ 的 deque 容器
    一、deque概述vector是单向开口的连续线性空间,deque则是一种双向开口的连续线性空间。所谓双向开口,意思是可以在头尾两端分别做元素的插入和删除操作,如下所示。vector也可以在头尾两端进行操作,但是其头部操作效率奇差,无法被接受。deque和vector的最大差异,一在于deque允许......
  • C++ IO流:控制台输入输出
    C++输入输出头文件#include<iostream>,常用于控制台打印/OJ数据读取分别对应:控制台IO流/文件流/字符串流,本文主要介绍控制台输出输出流cin>>空格分隔cout<<控制台输出已知待读取元素的数量:cin>>n未知待读取元素的数量:while(cin>>val)另外,可以整行读取数据,然......
  • MySQL 中 不等于 会过滤掉 Null 的问题
    在写SQL条件语句时经常用到不等于 != 的筛选条件。  此时要注意此条件会将字段为 Null 的数据也当做满足不等于的条件而将数据筛选掉。例:表AA1B110213Null执行如下查询:SELECT*FROMAWHEREB1!=1;得到的结果如下:A1B110第三......
  • C++数据结构之:栈Stack
    摘要:  it人员无论是使用哪种高级语言开发东东,想要更高效有层次的开发程序的话都躲不开三件套:数据结构,算法和设计模式。数据结构是相互之间存在一种或多种特定关系的数据元素的集合,即带“结构”的数据元素的集合,“结构”就是指数据元素之间存在的关系,分为逻辑结构和存储......
  • 【C++】初始化列表、隐式转换、static成员、友元与匿名对象
    文章目录1.初始化列表2.explicit关键字2.1隐式类型转换2.2explicit3.static成员3.1成员变量3.2成员函数4.友元4.1友元函数4.2友元类5.内部类6.匿名对象1.初始化列表在创建对象时,编译器通过调用构造函数,给对象中各个成员变量一个合适的初始值。classDate{publ......
  • 校园导航系统C++
    制作一个简单的大学城导航系统,根据用户指定的起点和终点,求出最短路径长度以及具体路径。项目要求:1)程序与数据相分离,地图中的所有数据都是从文件读入,而不是写在代码中2)最短路径算法不能调用函数库3)菜单界面可以循环显示,每次显示前先清屏4)输入的起点和终点若不存在,能给出相......
  • Linux C进阶 —— 与C++互相调用
      本文介绍C、C++函数互相引用的方法,以及各类目标文件(含.o目标文件、.a静态库、.so动态库)在互调使用中的详细编译链接方法。本文使用arm的交叉编译工具链作为编译和链接工具。1.C调用C++方法(asio为c++库)示例源码树:$tree..├──include│├──asio││├──......
  • c++结构体解决复数辐角问题
     结构体相关知识及运行代码(来自发发老师)/*ch10_structs.cc介绍:这里解释了结构体的使用方法。包括:(1)定义和初始化。(2)赋值。(3)结构体和数组一起使用。注意数据成员和函数成员的访问。(4)结构体和向量一起使用。(5)结构体和函数。*/#include<iostream>......
  • 【c++基础(五)】内存管理--new
    1.前言在C语言中,有四个内存管理函数:malloc,calloc,realloc和free但是使用起来他们却是非常的不方便:int*p1=(int*)malloc(sizeof(int)*n);int*p2=(int*)calloc(4,sizeof(int));int*p3=(int*)realloc(p2,sizeof(int)*10);同时这里也会出现一个问题,malloc不会进......
  • 【c++基础(四)】类和对象下--初始化列表等概念
    1.前言类和对象到这里基本已经接近尾声,本篇文章主要介绍一些与类和对象有关的相关细节,在后续使用类和对象中也有可能用的到。本章重点:本篇文章重点讲解初始化列表,友元,匿名对象和类中的static成员,以及类中的内部类的概念。 2.初始化列表 在谈论初始化列表之前就要再次......