首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【代码规范】详解nullptr、NULL、0

【代码规范】详解nullptr、NULL、0

作者头像
用户5521279
发布2019-09-16 16:24:32
1.4K0
发布2019-09-16 16:24:32
举报
文章被收录于专栏:搜狗测试搜狗测试搜狗测试

【代码规范】详解nullptr、NULL、0

最近一直搞不清楚 nullptr, NULL, '\0'这三者的真正区别,因为有的时候会发现,混用这三种用法,编译器也不会报错,在这里对相关的一些定义和使用方式进行整理,用于后续的使用说明。

欢迎大大们纠错~

null 和 NULL

C和C++语言对大小写是敏感的,也就是说null和NULL本质上是区别对待的。其实本质上null和NULL都是符号,只是在不同的编译器上NULL被宏定义指定内容,null没有定义而已。

例如在vs环境中,NULL被指定为0,代码如下。

我们可以这样写去验证以上的说法:

结果如下:

虽然可以这样使用,但是为了代码的可读性和规范着想,我们尽量不要编写这样的代码,了解原理即可。

NULL 和 nullptr

根据上面,我们知道了NULL本身是符号,只是不同编译器给出了不同的定义。刚刚看到了vs的定义,下面看下gcc对NULL的定义:

1) 如果gcc是c 语言模式而且gcc版本低于3.0,那么定义NULL 为 void* 类型

2) 如果gcc是c++ 语言模式,而且是32位,那么定义NULL 为无类型的0

3) 如果gcc是c++ 语言模式,而且是64位,那么定义NULL 为long long 类型的0

既然NULL可以被定义成不同的类型,那么为什么会出现nullptr呢,具体原因大家可以看下以下的代码,究竟是哪个函数会被调用。

发现在大多数的环境下结果如下,函数2无法调用。

为了解决这种二义性,nullptr应运而生,C++是强类型语言,又有模板、重载之类需要编译器“依类型随机应变”的东西,所以作为指针

型的0和整数类型的0就必须分开,不然会带来很多麻烦。

所以,和整数大家族相关,请用0(或自己重新定义的NULL,因为某些工程/实现可能把NULL定义成nullptr或者(void*) 0),和指针大家族相关,请用nullptr,这样才能写出尽量不出意外的程序。

NULL 和 0

其实NULL和0的关系在上面已经讲的差不多了,因为C++中不能将void *类型的指针隐式转换成其他指针类型,而又为了解决空指针的问题,所以C++中引入0来表示空指针,在一些编译器上又会用#define NULL ((void *)0)进行定义。

实际上C++的书都会推荐说C++中更习惯使用0来表示空指针,因为使用0来做为空指针会比使用NULL来做空指针会让你在编程时更加警觉,不过0代表空指针并不能避免上面说的二义性的问题,真正解决问题还得依靠nullptr。所以再次重复下,和整数大家族相关,请用0,和指针大家族相关,请用nullptr。

0的相关

‘\0’是一个“空字符”常量,它表示一个字符串的结束,它的ASCII码值为0,与’0‘的ASCII码值48是不一样的。

一般来说 0是整形常量,‘\0’是字符常量,存储方式不同,但是空字符的定义为“所有的位为 0 的字节称为 空字符(null character)”。也就是说,空字符是值为 0 的字符。,'\0'是一个常量,等同于0,(这个地方理解的不够深入)。

‘0’ 代表字符0, ASCII码为48。

“0”代表字符串0,尾部有不可见的’\0‘。

这个地方有一些需要注意的一些使用方法如下,代码如下图:

看起来执行结果没有什么问题,你可能会说说来说去,那还不都是 0 嘛。

确实在大部分的情况下是这样的,但背后的事情却异常复杂。标准允许将 NULL 定义成 (void*)0,所以在 NULL 被定义成 (void*)的时候,如果使用 NULL 来结束字符串,编译器必然会提示警告存在可能性空指针的区域并未清0,引发未知的错误。

所以在C++中NULL不可以用于字符串的末尾,支持0和'\0'作为字符串结尾。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-09-10,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 搜狗测试 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档