1.nullprt与NULL

代码:

void f(int i) {    cout << "f(int)" << endl;}

void f(char* c) {    cout << "f(char*)" << endl;}int main () {
    f();
    f('\0');
    // f(NULL); 在我的GCC中编译不过,因为NULL被认为是(void*)0,二义性
    // f((void*)0); 二义性
    f(nullptr);

    ;
}

结果:

因为NULL容易出问题,因此出现了nullptr。nullptr是有类型的,并且可以被隐式转化为指针类型。

额外:NULL,0,'\0' 的区别

NULL在 "stdio.h" 中的定义如下:

#ifndef __cplusplus
#define NULL ((void *)0)
#else   /* C++ */
#define NULL 0
#endif  /* C++ */

说明NULL在C中是(void*)0,而在C++中是0.

注意:0对于指针来说是一个特别对待的值,"当常量0处于应该作为指针使用的上下文中时,它就作为空指针使用“

如下程序所示;

int main () {
    void* p;
    p = 0;
    //p = 1; 这里报错了,虽然与0都是int类型
    cout << p << endl;
    return 0;
}

而'\0'是所有位都是0的字节,在ASCII码表中所示如下:

有趣的情况:C的字符串是用'\0'结尾的,而有的系统(比如Ubuntu14.04)用NULL也能结束(不过这在其他系统不一定能行得通):

int main () {
    char str[3];
    str[0] = 'a';
    str[1] = 'b';
    cout << str << endl;
    str[2] = '\0';
    cout << str << endl;
    str[2] = 0;
    cout << str << endl;
    return 0;
}

结果:

这三个都是表现出0,但是你的0不是我的0,如下代码:

int main () {
    cout << "\\0的大小:  " << sizeof('\0') << endl;
    cout << "0的大小:   " << sizeof(0) << endl;
    cout << "NULL的大小:" << sizeof(NULL) << endl;
    return 0;
}

结果:

总:这三者都是零,但是NULL是16进制的0(对于C来说这是(void*)0,是指针),0是10进制的0,'\0'是8进制的0

PS:上面NULL可以替代'\0'的情况可以理解为,在二进制中,NULL是16个0而'\0'是8个0,NULL可以截断最后8位成为'\0'。


  2.nullptr是关键字


  3.nullptr的类型是nullptr_t

使用nullptr_t需要包含<cstddef>,其定义为typedef decltype(nullptr) nullptr_t;

使用nullptr_t可以定义多个指针空值,而不仅仅是nullptr一个(虽然nullptr已经够用了)

int main () {
    nullptr_t myNull;
    f(myNull);

    ;
}

规则:

  • nullptr_t类型数据可以隐式转换成任意一个指针类型。
  • nullptr_t类型数据不能转换为非指针类型,即使reinterpret_cast
  • nullptr_t类型数据不适用于算术运算表达式。
  • nullptr_t类型数据适用于关系算术表达式,但仅能与nullptr_t和指针类型比较。

  

  4.nullptr与模板

模板只把nullptr作为一个普通的类型进行推导(并不会视为T* 指针)

template<typename T> void g(T* t) { cout << sizeof(T) << endl;}

template<typename T> void h(T t) { cout << sizeof(T) << endl;}

int main () {
    // g(nullptr); 类型是nullptr_t而不是指针
    g(();
    g((int*)nullptr);

    h();
    h(nullptr);
    h((int*)nullptr);

    ;
}


  5.规定sizeof(nullptr_t) == sizeof(void*)

nullptr是一个编译时期的常量,是编译时期的关键字,能被编译器识别。(void*)0需要经过类型转换才能变成其他指针类型。


  6.nullprt地址

  • 可以打印nullptr_t对象的地址
  • 不能直接打印nullptr的地址
  • 可以打印nullptr的右值引用的地址

代码:

int main () {
    nullptr_t my_null;
    cout << &my_null << endl; //可以打印nullptr_t的地址

    // cout << nullptr << endl; 错误

    const nullptr_t &nullptr_r = nullptr; //可以打印nullptr的右值引用地址
    cout << &nullptr_r << endl;

    ;
}

参考书籍:《深入理解C++11》

C++11---nullptr的更多相关文章

  1. C++ 11 nullptr关键字

    熟悉C++的童鞋都知道,为了避免“野指针”(即指针在首次使用之前没有进行初始化)的出现,我们声明一个指针后最好马上对其进行初始化操作.如果暂时不明确该指针指向哪个变量,则需要赋予NULL值.除了NUL ...

  2. C++11 并发指南一(C++11 多线程初探)

    引言 C++11 自2011年发布以来已经快两年了,之前一直没怎么关注,直到最近几个月才看了一些 C++11 的新特性,今后几篇博客我都会写一些关于 C++11 的特性,算是记录一下自己学到的东西吧, ...

  3. C++11 并发指南一(C++11 多线程初探)(转)

    引言 C++11 自2011年发布以来已经快两年了,之前一直没怎么关注,直到最近几个月才看了一些 C++11 的新特性,今后几篇博客我都会写一些关于 C++11 的特性,算是记录一下自己学到的东西吧, ...

  4. 【C/C++开发】C++11 并发指南一(C++11 多线程初探)

    引言 C++11 自2011年发布以来已经快两年了,之前一直没怎么关注,直到最近几个月才看了一些 C++11 的新特性,今后几篇博客我都会写一些关于 C++11 的特性,算是记录一下自己学到的东西吧, ...

  5. C++学习笔记28:运行期型式信息

    RTTI 运行期标识对象的型式信息 优势:允许使用指向基类的指针或引用自如地操作派生类的对象 typeid:获取表达式的型式:type_info:型式信息类 头文件:typeinfo 对象转型模板 d ...

  6. 译注(3): NULL-计算机科学上最糟糕的失误

    原文:the worst mistake of computer science 注释:有些术语不知道怎么翻译,根据自己理解的意思翻译了,如有不妥,敬请提出:) 致谢: @vertextao @fra ...

  7. 地区sql

    /*Navicat MySQL Data Transfer Source Server : localhostSource Server Version : 50136Source Host : lo ...

  8. C++11特性——变量部分(using类型别名、constexpr常量表达式、auto类型推断、nullptr空指针等)

    #include <iostream> using namespace std; int main() { using cullptr = const unsigned long long ...

  9. C++11 之 nullptr

    C++11 中,nullptr 是空指针,可用来给 (指向任意对象类型的) 指针赋值 广义整型 (integral types) = char, short, int, long, long long ...

  10. c++11编码规范 NULL还是nullptr

    0和nullptr/NULL 至于指针(地址值),根据实际选择用0.NULL还是nullptr.对使用了C++11特性的项目,选用nullptr:对于C++03项目,推荐NULL,因为它像是一个指针

随机推荐

  1. Android 编程下的自定义 xmlns

    什么是 xmlns xmlns是 XML Namespaces 的缩写,中文名称是 XML命名空间. xmlns 使用规则 xmlns:namespace-prefix="namespace ...

  2. Angular JS 学习之Http

    1.$http是AngularJS中的一个核心服务,用于读取远程服务器的数据: 2.读取JSON文件: **JSON文件如下: { "sites":[ { "Name&q ...

  3. 20145223《Java程序程序设计》第1周学习总结

    20145223 <Java程序设计>第1周学习总结 教材学习内容总结 1.JDK.JRE以及JVM的区别 JDK:撰写java程序语言的时候需要用到的编译工具 JRE:java执行环境 ...

  4. Scau 8633 回文划分 mancher + dp

    时间限制:1000MS 内存限制:1000K 提交次数: 通过次数: 题型: 编程题 语言: G++;GCC Description 我们说一个字符串是回文串,那么意味着这个串从两边读起来的字母都是一 ...

  5. Hibernate,一对一外键单向 记录。Timestamp 的一个坑。

    首先是2张表 表A: 表B: 其中表B中的FormBaseId对应表A中的SubjectID. 数据库中没有设置外键关系. 下面是2个对应的实体 package questionnaire.model ...

  6. linux系统下本地搭建git服务器

    linux系统下如何搭建本地git服务器,用于存放团队的开发代码,如下步骤: 1.先用一台服务器来安装git,安装好linux以后,在这里选用的是Ubuntu 14.04.然后配置静态IP:172.1 ...

  7. jquery事件重复绑定解决办法

    一$.fn.live 重复绑定 解决:使用die()方法,在live()方法绑定前,将此元素上的前面被绑定的事件统统解除,然后再通过live()方法绑定新的事件. //先通过die()方法解除,再通过 ...

  8. java基础-操作符

    浏览以下内容前,请点击并阅读 声明 定义:操作符是一种能够对一个,两个或三个操作对象执行特定的操作,并返回一个结果的特定符号. java中操作符的种类和优先级如下表所示,除了赋值运算,所有二元操作符运 ...

  9. BZOJ4662 : Snow

    首先离散化,即相邻关键点之间的部分可以压成一段. 注意到区间互不包含,因此排序后每个位置的清理影响到的是一段连续区间的清理工的工作长度. 这显然可以用线段树维护,支持区间减去一个数,单点加上$inf$ ...

  10. centos 编译 安装 protobuf

    link:http://dbua.iteye.com/blog/1633079 yum -y install gcc+ gcc-c++ yum -y install make 下载protobuf-2 ...