某些时候,我们需要将指针赋值为空指针,以防止野指针。
 
有人喜欢使用NULL作为空指针常量使用,例如:int* p = NULL;。
也有人直接使用0值作为空指针常量,例如:int* p = 0;。
 
前者可能觉得:NULL作为空指针常量,名字很形象,可读性较强。
后者可能觉得:NULL并不是C/C++语言的关键字,而是一个在标准库头文件<stddef.h>中定义的宏,因此要使用NULL,可能需要直接或简介地包含<stddef.h>头文件,比较麻烦。
 
问题一:NULL与常数0值有何区别?
 
要弄清楚这个问题,我们采用问与答的形式来描述。
 
问:NULL到底是什么?
 
答:NULL是一个宏。
 
问:它的值是多少?
 
答:C/C++标准规定:它的值是一个空指针常量(null pointer constant),由实现定义。#1,#2
 
问:什么样的值才能称之为空指针常量?
 
答:C语言中常数0和(void*)0都是空指针常量;C++中(暂且忽略C++11)常数0是,而(void*)0 不是。#3,#4
 
问:NULL宏是在哪里定义的?
 
答:通常是在C标准库的<stddef.h>头文件中,不过别的头文件中可能也有定义。
 
问:一般编译器的<stddef.h>头文件中NULL宏是如何定义的?
 
答:以gcc或clang编译器为例,NULL的定义大致如下(稍有简化):
  1. #if defined(__cplusplus)
  2. # define NULL // C++中使用0作为NULL的值
  3. #else
  4. # define NULL ((void *)) // C中使用((void *)0)作为NULL的值
  5. #endif
问:为什么C中(void*)0是空指针常量,而C++中不是?
 
答:因为C语言中任何类型的指针都可以(隐式地)转换为void*型,反过来也行,而C++中void*型不能隐式地转换为别的类型指针(例如:int*p = (void*)0;使用C++编译器编译会报错)。#5,#6
 
问:既然C/C++标准中,常数0都可作为空指针常量,为什么不统一使用0?
 
答:个人觉得由于(void*)0更能体现指针的意义,而常数0更多的时候是用作整数。因此,C语言中NULL定义选择了(void*)0。(仅供参考)
 
问题二:C++11中为什么要引入nullptr?
 
考虑着这样一个函数重载的情形:
  1. #include <stddef.h>
  2. void foo(int) {} // #1
  3. void foo(char*) {} // #2
  4. int main() {
  5. foo(NULL); // 调用#1还是#2?
  6. }
从字面上来讲,NULL是个空指针常量,我们可能会觉得:既然是个指针,那么应该调用#2。但事实上调用的却是#1,因为C++中NULL扩展为常数0,它是int型。
 
根本原因就是:常数0既是整数常量,也是空指针常量。
 
为了解决这种二义性,C++11标准引入了关键字nullptr,它作为一种空指针常量。#7例如:
 
  1. void foo(int) {} // #1
  2. void foo(char*) {} // #2
  3. int main() {
  4. foo(nullptr); // 它会毫无异议地调用#2
  5. }
附注:
 
[#1] C99: 7.17-p3:
    The macros are
        NULL
    which expands to an implementation-defined null pointer constant; and ...
 
[#2] C++03: 18.1-p4:
    The macro NULL is an implementation-defined C + + null pointer constant in this International Standard(4.10).
 
[#3] C99: 6.3.2.3-p3:
    An integer constant expression with the value 0, or such an expression cast to type void *, is called a null pointer constant.
 
[#4] C++03: 4.10-p1:
    A null pointer constant is an integral constant expression (5.19) rvalue of integer type that evaluates to zero.
 
[#5] C99: 6.3.2.3-p1:
    A pointer to void may be converted to or from a pointer to any incomplete or object type. A pointer to any incomplete or object type may be converted to a pointer to void and back again; the result shall compare equal to the original pointer.
 
[#6] C++03: 4.10-p2:
    An rvalue of type “pointer to cv T,” where T is an object type, can be converted to an rvalue of type “pointer to cv void.”
 
[#7] C++11: 4.10-p1:
    A null pointer constant is an integral constant expression (5.19) prvalue of integer type that evaluates to zero or a prvalue of type std::nullptr_t.
 
参考:
 
(1) C99/C++03/C++11标准文档
 

C/C++杂记:NULL与0的区别、nullptr的来历的更多相关文章

  1. 【转载】C/C++杂记:NULL与0的区别、nullptr的来历

    原文:C/C++杂记:NULL与0的区别.nullptr的来历 某些时候,我们需要将指针赋值为空指针,以防止野指针.   有人喜欢使用NULL作为空指针常量使用,例如:int* p = NULL;. ...

  2. 字符串怎么换行 || 字符串中使用单引号时应该怎么写 || 保留两位小数 || 数字0在if中的意思是false || 什么情况下会会报undefined || null和undefined的区别 ||

    换行的字符串 "This string\nhas two lines" 字符串中使用单引号时应该怎么写 'You\'re right, it can\'t be a quote' ...

  3. php中0," ",null和false的区别

    php中很多还不懂php中0,"",null和false之间的区别,这些区别有时会影响到数据判断的正确性和安全性,给程序的测试运行造成很多麻烦.先看一个例子: <? $str ...

  4. c语言NULL和0区别及NULL详解

      先看下面一段代码输出什么: #include<stdo.h> int main() { int *p=NULL; printf("%s",p); } 输出<n ...

  5. C/C++编程笔记:C语言NULL值和数字 0 值区别及NULL详解

    在学习C语言的时候,我们常常会碰到C语言NULL值和数字 0 ,很多小伙伴搞不清楚他们之间的一个区别,今天我们就了解一下他们之间的区别,一起来看看吧! 先看下面一段代码输出什么: 输出<null ...

  6. NULL, '\0',0 '0'的区别

    如题,在程序中经常遇到NULL,和'\0',常常疑惑它们是什么关系,其实它们的值是一样的,只不过表现的形式不一样: 1.NULL; NULL 即空指针,在C和C++中的形式不一样,msdn上有如下的内 ...

  7. php中0,空,null和false的区别

    <? $str1 = null; $str2 = false; echo $str1==$str2 ? ‘相等’ : ‘不相等’; $str3 = ""; $str4 = 0 ...

  8. C/C++语言中NULL、'\0’和0的区别

    注:本文参考了http://blog.csdn.net/mylinx/article/details/6873253及书籍<征服C指针>([日]前桥和弥著). NULL.'\0'和0的值是 ...

  9. 史上最明白的 NULL、0、nullptr 区别分析(老师讲N篇都没讲明白的东东),今天终于明白了,如果和我一样以前不明白的可以好好的看看...

    C的NULL 在C语言中,我们使用NULL表示空指针,也就是我们可以写如下代码: int *i = NULL; foo_t *f = NULL; 实际上在C语言中,NULL通常被定义为如下: #def ...

随机推荐

  1. The Dominator of Strings HDU - 6208(ac自动机板题)

    题意: 就是求是否有一个串 是其它所有串的母串 解析: 把所有的串都加入到trie数中  然后用最长的串去匹配就好了 emm..开始理解错题意了...看成了只要存在一个串是另一个的母串就好.. 然后输 ...

  2. Just Another Problem UVA - 11490(枚举)

    题意: 你有s个士兵,并打算把他们排成一个r行c列,但有两个"洞"的矩形方队,以迷惑敌人(从远处看,敌人可能误以为一共有r*c个士兵).洞是两个大小相同的正方形,为了隐蔽性更强,方 ...

  3. 【hihocoder编程练习赛9】闰秒

    题目链接 #include<stdio.h> #include<string.h> #include<algorithm> #include<math.h&g ...

  4. Crawl(2)

    http://cuiqingcai.com/3179.html # *-* coding: UTF-8 *-* import urllib2 import cookielib import re im ...

  5. [Ispc2009]Let there be rainbows!

    Description HY Star是一个处处充满和谐,人民安居乐业的星球,但是HYStar却没有被评上宇宙文明星球,很大程度上是因为星球的形象问题. HY Star由N个国家组成,并且在一些国家之 ...

  6. NEERC 15 (10/12)

    NEERC=Not Easy European Regional Contest 据说NEERC天天被搬,赶紧做了好了.在Claris和Google的帮助下做了10题,感谢cls. http://co ...

  7. 【转】查看 Linux 发行版名称和版本号的 8 种方法

    如果你加入了一家新公司,要为开发团队安装所需的软件并重启服务,这个时候首先要弄清楚它们运行在什么发行版以及哪个版本的系统上,你才能正确完成后续的工作.作为系统管理员,充分了解系统信息是首要的任务. 查 ...

  8. 【Cf #299 C】Tavas and Pashmaks(单调栈,凸性)

    一个经典的二维数点模型,如果某个人 $ x $ 两个速度都比另一个人 $ y $ 大,显然 $y$ 是不可能成为winner的. 但这里只考虑两个人$x$,$y$在两个属性各有千秋的时候,一定存在正整 ...

  9. 【模板】exBSGS/Spoj3105 Mod

    [模板]exBSGS/Spoj3105 Mod 题目描述 已知数\(a,p,b\),求满足\(a^x\equiv b \pmod p\)的最小自然数\(x\). 输入输出格式 输入格式: 每个测试文件 ...

  10. PyPt5 浏览器实例

    title: PyPt5 浏览器实例 date: 2018-02-02 13:40:03 tags: Python PyQt5 便携浏览器 categries: Python --- 导入包 pyQt ...