热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

c语言null和space,C++11NULL和nullptr

众所周知,C语言使用NULL常量来表示空指针,为什么C11还要增加新的nullptr来表示空指针呢?1,我们首先查看NULL

众所周知,C语言使用NULL常量来表示空指针,为什么C++11还要增加新的nullptr来表示空指针呢?

1,我们首先查看NULL的定义:

#if defined (_STDDEF_H) || defined (__need_NULL)

#undef NULL             /* in case has defined it. */

#ifdef __GNUG__

#define NULL __null

#else   /* G++ */

#ifndef __cplusplus

#define NULL ((void *)0)

#else   /* C++ */

#define NULL 0

#endif  /* C++ */

#endif  /* G++ */

#endif  /* NULL not defined and or need NULL.  */

#undef  __need_NULL

从上面的定义可以看出,如果定义了__GNUG__,编译器NULL其实就是__null,__null是编译器相关的行为(要么是常量0,要么是 (void *)0),有待进一步研究确认。

因此,在C语言中,如下定义都是合法的:

int a = NULL;

char b = NULL;

int *ptr = NULL;

2,在C++中,考虑如下重载示例:

void overloaded(int value) {

std::cout <<"int value" <

}

void overloaded(int *ptr) {

std::cout <<"int *ptr" <

}

int main() {

overloaded(NULL);        // 歧义&#xff0c;因为NULL既可以是常量0&#xff0c;也可以是 void*指针。

return 0;

}

由于C&#43;&#43;支持函数重载&#xff0c;此时NULL的定义就会带来歧义&#xff0c;当我们调用overloaded(NULL)&#xff1b;的时候&#xff0c;编译器无法确认&#xff0c;到底是把NULL作为常量0还是作为 (void *)0&#xff0c;因此编译无法通过。

为了解决这个问题&#xff0c;C&#43;&#43;11引入了nullptr常量&#xff0c;该常量是std::nullptr_t类型。std::nullptr_t类型可以转换为任意指针类型(类似于void *&#xff0c;也可以转换为任意指针类型)&#xff0c;同时也可以转换为bool类型(用以支持条件判断 !ptr)&#xff0c;但是不能转换成整型类型。这样便消除了上面的重载歧义。

overloaded(nullptr);   // ok&#xff0c;调用void overloaded(int *ptr);版本

转换成bool类型示例如下&#xff1a;

int main() {

std::nullptr_t ptr &#61; nullptr;

if (!ptr) {    // std::nullptr_t类型转换成bool类型

std::cout <<"nullptr" <

}

return 0;

}

3&#xff0c;当然&#xff0c;nullptr只是解决了整型和指针类型的重载问题&#xff0c;对于两个不同指针类型的重载函数&#xff0c;nullptr无法区分出来&#xff1a;

void overloaded(int *ptr) {

std::cout <<"int *ptr" <

}

void overloaded(char *ptr) {

std::cout <<"char *ptr" <

}

int main() {

overloaded(nullptr);    // 歧义&#xff0c;依然无法区分 int *和 char *

return 0;

}

这时候&#xff0c;可以使用std::nullptr_t类型&#xff0c;如下&#xff1a;

void overloaded(int *ptr) {

std::cout <<"int *ptr" <

}

void overloaded(char *ptr) {

std::cout <<"char *ptr" <

}

void overloaded(std::nullptr_t ptr) {

std::cout <<"std::nullptr_t ptr" <

}

int main() {

overloaded(nullptr);    // ok&#xff0c;输出 std::nullptr_t ptr

return 0;

}



推荐阅读
  • Java SE从入门到放弃(三)的逻辑运算符详解
    本文详细介绍了Java SE中的逻辑运算符,包括逻辑运算符的操作和运算结果,以及与运算符的不同之处。通过代码演示,展示了逻辑运算符的使用方法和注意事项。文章以Java SE从入门到放弃(三)为背景,对逻辑运算符进行了深入的解析。 ... [详细]
  • 本文介绍了基于c语言的mcs51单片机定时器计数器的应用教程,包括定时器的设置和计数方法,以及中断函数的使用。同时介绍了定时器应用的举例,包括定时器中断函数的编写和频率值的计算方法。主函数中设置了T0模式和T1计数的初值,并开启了T0和T1的中断,最后启动了CPU中断。 ... [详细]
  • C语言注释工具及快捷键,删除C语言注释工具的实现思路
    本文介绍了C语言中注释的两种方式以及注释的作用,提供了删除C语言注释的工具实现思路,并分享了C语言中注释的快捷键操作方法。 ... [详细]
  • 本文介绍了如何在给定的有序字符序列中插入新字符,并保持序列的有序性。通过示例代码演示了插入过程,以及插入后的字符序列。 ... [详细]
  • c语言\n不换行,c语言printf不换行
    本文目录一览:1、C语言不换行输入2、c语言的 ... [详细]
  • 本文介绍了C函数ispunct()的用法及示例代码。ispunct()函数用于检查传递的字符是否是标点符号,如果是标点符号则返回非零值,否则返回零。示例代码演示了如何使用ispunct()函数来判断字符是否为标点符号。 ... [详细]
  • 开发笔记:实验7的文件读写操作
    本文介绍了使用C++的ofstream和ifstream类进行文件读写操作的方法,包括创建文件、写入文件和读取文件的过程。同时还介绍了如何判断文件是否成功打开和关闭文件的方法。通过本文的学习,读者可以了解如何在C++中进行文件读写操作。 ... [详细]
  • OO第一单元自白:简单多项式导函数的设计与bug分析
    本文介绍了作者在学习OO的第一次作业中所遇到的问题及其解决方案。作者通过建立Multinomial和Monomial两个类来实现多项式和单项式,并通过append方法将单项式组合为多项式,并在此过程中合并同类项。作者还介绍了单项式和多项式的求导方法,并解释了如何利用正则表达式提取各个单项式并进行求导。同时,作者还对自己在输入合法性判断上的不足进行了bug分析,指出了自己在处理指数情况时出现的问题,并总结了被hack的原因。 ... [详细]
  • 本文介绍了在Windows系统上使用C语言命令行参数启动程序并传递参数的方法,包括接收参数程序的代码和bat文件的编写方法,同时给出了程序运行的结果。 ... [详细]
  • C语言判断正整数能否被整除的程序
    本文介绍了使用C语言编写的判断正整数能否被整除的程序,包括输入一个三位正整数,判断是否能被3整除且至少包含数字3的方法。同时还介绍了使用qsort函数进行快速排序的算法。 ... [详细]
  • 本文介绍了GTK+中的GObject对象系统,该系统是基于GLib和C语言完成的面向对象的框架,提供了灵活、可扩展且易于映射到其他语言的特性。其中最重要的是GType,它是GLib运行时类型认证和管理系统的基础,通过注册和管理基本数据类型、用户定义对象和界面类型来实现对象的继承。文章详细解释了GObject系统中对象的三个部分:唯一的ID标识、类结构和实例结构。 ... [详细]
  • 本文讨论了如何优化解决hdu 1003 java题目的动态规划方法,通过分析加法规则和最大和的性质,提出了一种优化的思路。具体方法是,当从1加到n为负时,即sum(1,n)sum(n,s),可以继续加法计算。同时,还考虑了两种特殊情况:都是负数的情况和有0的情况。最后,通过使用Scanner类来获取输入数据。 ... [详细]
  • 本文介绍了一种划分和计数油田地块的方法。根据给定的条件,通过遍历和DFS算法,将符合条件的地块标记为不符合条件的地块,并进行计数。同时,还介绍了如何判断点是否在给定范围内的方法。 ... [详细]
  • 3.223.28周学习总结中的贪心作业收获及困惑
    本文是对3.223.28周学习总结中的贪心作业进行总结,作者在解题过程中参考了他人的代码,但前提是要先理解题目并有解题思路。作者分享了自己在贪心作业中的收获,同时提到了一道让他困惑的题目,即input details部分引发的疑惑。 ... [详细]
  • 本文讨论了编写可保护的代码的重要性,包括提高代码的可读性、可调试性和直观性。同时介绍了优化代码的方法,如代码格式化、解释函数和提炼函数等。还提到了一些常见的坏代码味道,如不规范的命名、重复代码、过长的函数和参数列表等。最后,介绍了如何处理数据泥团和进行函数重构,以提高代码质量和可维护性。 ... [详细]
author-avatar
鬼王守护灵
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有