NULL,nullptr与0

0

NULL

C语言中

C++中

隐式类型转换

nullptr

预处理中的条件编译语句

0

在我们的程序中,单纯一个0,在不同的类型中有着不同的意思

0,是一个空字符常量,他在ASCII中的序号就是0,是一个字符串的结束标准

‘0’,表示一个字符'0',他在ASCII中的序号是48

“0”,表示一个字符串"0",他的大小是2,因为在他的末尾还需要有一个0来表示字符串结束的标志

NULL

NULL就是我们在程序中经常见到的空指针,他所在的头文件是stddef.h,他所指向的地址是0x00 00 00 00

这个地址默认是一个不能被访问的地址,只要被访问就会报错

但是NULL并不是我们所见到的几个基本类型的数据,他在底层中是一个宏,但是对于C语言和C++语言而言,他却是有着不同的定义

C语言中

#undef NULL

#define NULL ((void *)0)

在C语言中,NULL被宏定义为((void *)0)

C++中

vs编译器中的定义

/* Define NULL pointer value */

#ifndef NULL

#ifdef __cplusplus

#define NULL    0

#else  /* __cplusplus */

#define NULL    ((void *)0)

#endif  /* __cplusplus */

#endif  /* NULL */

可以看到,C++为了向下兼容C语言的一些语法,在NULL的定义中,加入了判断

要是C程序,则进行#define NULL ((void *)0)

要是C++程序,则进行#define NULL 0

利用 __cplusplus判断程序的类型

如果一段代码是需要针对C++编写的, 可以使用该宏进行条件编译。__cplusplus的值是为了表示C++的版本。__cplusplus的类型是long int

void Type()

{

#ifdef __cplusplus

printf("This is c++ program %d\n",__cplusplus);

#else

printf("This is c program");

#endif

}

如果没有定义__cplusplus, 那么当前源代码被当作C源代码处理。

如果定义了__cplusplus,那么当前源代码被当中C++源代码处理, 并且输出__cplusplus宏被展开后的字符串。

当我们使用((void *)0)在C++中进行转换的时候,其实是会出错的

这说明,在C++中是不支持(void*) 0的,这是因为C++中(void*)类型是不支持隐式类型转换的。

因为,C++中存在隐式类型的转换,而当转换的类型是(void*)类型时,对方并不知道这个数据原本的类型是多大,如果在不清楚对方类型的情况下,强制进行转换,很有可能会出现越界访问的情况,或者出现脏数据

隐式类型转换

C++中的基本类型并不是绝对的,部分数据类型之间是可以进行隐式转换的。隐式转换指的是不需要我们进行干预,编译器私下进行的类型转换行为。这个过程是我们看不到的

就像

int a = 1;

char b = 'a';

long long c = a + b;

在第三步中,他其实会把int型的变量a和char型的变量b隐式的转换为double类型的变量

也就是说,隐式类型转换中,他得满足一点就是,只能有低精度的数据类型转为高精度的数据类型。(因为高精度转低精度的话,很容易出现溢出的情况)当然,如果我们确定数据不会溢出,是可以自定义从高精度强转为低精度数据类型的。

但是这种隐式类型的转换,C语言也是支持的,那么为什么C++还不允许(void*)0,别忘了,C++还有一个自定义类型的类

当我们创建一个类,这个类中有6个默认的成员函数,分别是构造,析构,拷贝,赋值运算符重载,还有对普通对象和const对象的取地址操作。

我们写一个类的时候,给他写一个构造函数。构造函数不仅可以构造与初始化对象,他们对于单参数的构造函数,还有着类型转换的作用

class Test

{

public:

Test(int a)

:val(a)

{}

bool isSame(Test obj)

{

return val == obj.val;

}

private:

int val;

};

在这一步中,我们调用a.isSame(10)进行比较的时候,其实发生了隐式类型转换。

在世界调用中,a.isSame(10)其实是这样进行变换的a.isSame((Test)10),他将我们所传的参数,隐式转换成了Test这个类的类型,然后在底层比较两个类的值是否相同。但是实际我们是想比较Test和int类型数据的不同。

所以说,如果C++的NULL这个宏支持(void*)0的时候,那么他在隐式类型转换中就会出错,所以C++中的NULL其实就可以看成是一个0

nullptr

在C++11中引入了nullptr这一空指针的类型,至于为什么要引入nullptr

void Fun(int var)

{

cout << "Fun(int var) " << var << endl;

}

void Fun(int* var)

{

cout << "Fun(int* var) " << var << endl;

}

int main()

{

int* p = NULL;

Fun(p);  // -->  void Fun(int* var)

Fun(NULL);// -->  void Fun(int var)

return 0;

}

NULL,本身应该是一个指针的类型,但是在实际调用中却会变成数据类型,这和指针类型发生了二义性。

所以在C++11中,就可以使用nullptr来代替空指针,那么没有nullptr的时候,我们是怎么实现的呢?

const class nullptr_t

{

public:

template

inline operator T*()const

{

return 0;

}

template

inline operator T C::*()const

{

return 0;

}

private:

void operator&()const;

}nullptr = {};

所以说,在C++中,当涉及到空指针的时候,就使用nullptr;NULL就当成0的一个宏定义来使用就o了

预处理中的条件编译语句

#define ,定义一个预处理宏

#undef,取消宏的定义

#if ,编译预处理中的条件命令,相当于C语法中的if语句

#ifdef,判断某个宏是否被定义,若已定义,执行随后的语句

#ifndef ,与#ifdef相反,判断某个宏是否未被定义

#elif ,若#if, #ifdef, #ifndef或前面的#elif条件不满足,则执行#elif之后的语句,相当于C语法中的else-if

#else,与#if, #ifdef, #ifndef对应, 若这些条件不满足,则执行#else之后的语句,相当于C语法中的else

#endif , #if, #ifdef, #ifndef这些条件命令的结束标志.

defined ,与#if, #elif配合使用,判断某个宏是否被定义

C语言nullptr错误,c/c++中的NULL,nullptr,0相关推荐

  1. C语言nullptr错误,C/C++中的NULL与nullptr

    C中的NULL 在C语言中我们将NULL用作空指针之用,NULL在C语言中的定义如下: #define NULL ((void *)0) 可以看到,C语言中NULL是一个void*指针,我们常用其来对 ...

  2. C语言nullptr错误,C ++中的nullptr到底是什么

    对于有经验的C ++和那些了解现代C ++编程语言的人来说,C ++中的nullptr到底是什么,这将是非常简单的问题.但是nullptr不仅是C ++中的编程语言,而且为了解释这一点,我们先了解一下 ...

  3. C语言nullptr错误,编译错误'nullptr'未声明的标识符(Compile error 'nullptr' undeclared identifier)...

    编译错误'nullptr'未声明的标识符(Compile error 'nullptr' undeclared identifier) 我打算用Visual Studio 2008 Express编译 ...

  4. R语言ggplot2可视化在散点图中的每个点上绘制两个错误条:常见的是垂直错误条,它对应于Y值点上的错误(error bar),添加与X轴(水平)相关的错误条(error bar)

    R语言ggplot2可视化在散点图中的每个点上绘制两个错误条:常见的是垂直错误条,它对应于Y值点上的错误(error bar),添加与X轴(水平)相关的错误条(error bar) 目录

  5. 以下关于python语言技术特点_关于Python语言的特点,以下选项中描述错误的是

    关于Python语言的特点,以下选项中描述错误的是 答:Python语言是非开源语言 为<素问>补充了"天元纪大论"等7篇大论的医家是: 答:王冰 中国大学MOOC: ...

  6. 以下python注释代码、叙述中不正确的是_关于 Python 语言的注释,以下选项中描述错误的是( )_学小易找答案...

    [多选题]下列各项中,企业应通过"其他货币资金"科目核算的经济业务有( ). [其它][变式训练 3]如图所示,用与地面成30°角的300 N的力向右上方拉小车,画出该力的示意图. ...

  7. python语言特点以下错误的是_关于Python语言的特点,以下选项中描述错误的是( )。_学小易找答案...

    [其它]制作空间感雨幕效果 素材图如下: [单选题]1332 .定向井分为常规定向井.大斜度定向井和( A )三种类型. [填空题]用来设置表格边线粗细的属性是( ) [单选题]1320 .井下动力钻 ...

  8. 关于python语言数值操作符、以下选项错误的是 答案是_关于Python语言数值操作符,以下选项中描述错误的是...

    [单选题]关于Python的列表,以下选项中描述错误的是 [单选题]给定字典d,以下选项中对d.values()的描述正确的是 [单选题]下面代码的输出结果是 sum = 0 for i in ran ...

  9. Go 分布式学习利器(14)-- Go语言的错误处理

    1. Go 的错误机制 Go 语言的错误机制中与其他语言的主要差异如下: 没有异常机制 error 类型实现了 error接口 type error interface {Error() string ...

最新文章

  1. Java opengl openal_项目里用到了openal,特分享一下openal全教程
  2. bootstrap学习(一)栅格、布局
  3. nodejs连接池 连接关闭_「转」连接池居然这么简单?
  4. arduinowifi.send怎么获取响应_ChatterBot代码解读-获取对话
  5. 【深度】韦东山:一文看尽 linux对中断处理的前世今生
  6. python format 冒号_python之格式化输出
  7. 计算机系统结构自学试卷,全国2004年4月高等教育自学考试计算机系统结构试题...
  8. Jmeter系列之数据库操作
  9. Java compiler level does not match the version of the installed Java project fac
  10. 20190823:(leetcode习题)实现 strStr()
  11. istio使用教程和示例(导流,请求路由,访问拒绝,黑白名单,限速)
  12. ubuntu 20.04 安装可编辑截图工具 flameshot
  13. 删除mysql数据库_安装/删除MySQL数据库
  14. 4.4 输入法图片 android,支持安卓4.4!搜狗输入法5.1新版发布
  15. Thinkpad X1 Tablet gen2键盘改typec键线分离
  16. 解决网络和Internet设置中只有飞行模式的问题
  17. 第二次作业:微博案例分析
  18. 自然语言处理3 -- 词性标注
  19. 关于概率dp的个人理解与总结
  20. Linux就这个范儿 第14章 身在江湖

热门文章

  1. python爬虫教程:爬虫时如何知道是否代理ip伪装成功
  2. 常见的NTP授时服务器地址(本文不断更新中)
  3. omv检查硬盘坏道_用MHDD怎么修复硬盘坏道可行教程
  4. 一网打尽、详解面试最常被问到的几种 Python 设计模式
  5. 常用的英语口语(个人收藏)
  6. webshell之简单版本jsp
  7. liblinear实践初步
  8. vue 项目放弃“tui-editor“ “1.3.3“,
  9. 6-5 使用函数求余弦函数的近似值 (15分)
  10. MatLab linspace