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

2019-09-16 16:24:32 浏览数 (1)

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

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

欢迎大大们纠错~

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的相关

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

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

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

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

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

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

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

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

0 人点赞