目录

指针的非空判断问题:

NULL和nullptr的替换问题:

这里我对于NULL的二义性问题有两个理解:

总结:如果你的编译器支持nullptr的话,尽量选择去使用nullptr而不是NULL。

在更改NULL为nullptr时我遇到的问题:

NULL替换为nullptr编译器报错:


今天早上,在重新书写上文中的通过指针调换元素的程序的时候,加上了断言头文件。目的是增加指针的非空判断以及形参的有效范围使程序更安全,其实我对于断言语句的理解也仅仅局限于使程序更安全这一非常浅层的方面,到底为什么我也不知道,所以今天早上看了些文章对指针的非空判断做了一些了解,另外解决了在VScode中使用nullptr替换NULL程序运行报错的问题,简单做一下总结:

指针的非空判断问题:

#include<assert.h>

回想起以前老师讲课的时候书写利用指针的程序的时候,总是会在函数在最开始对指针进行非空判断。例如在上文指针的学习作业二中的调换函数:

void Reverse(int *ar,int begin_index,int end_index)
{assert(ar != NULL && begin_index >= 0 && end_index >= 0);int *p = ar + begin_index;int *q = ar + end_index; assert(p != NULL && q != NULL);while(p < q){Swap(p,q);p++;q--;}
}

注意,在这个函数中,数组在形参中退化成了指针,而我在函数内部又定义了p和q两个指针变量,这三个指针变量我全都在开始做了非空判断。

在前文中提到,指针的别名就是地址,在(int *p = ar + begin_index;)语句中,指针就是指向ar + begin_index的地址的变量,那么如果p指针不需要指向任何一个地址的话,我们就可以将p指针置空:

int *p = NULL;

空指针的地址是0x00000000,所以它不指向任何一个地方

所以我们就可以通过判断指针是否为空进而来判断指针是否有效,以防止程序崩溃。

前文中提到对指针进行解引用可以获取到它所指向的值。但从定义上来看,NULL指针并为指向任何东西。因此,对一个NULL指针进行解引用的操作是非法的。在对指针进行解引用之前,必须确保它不是一个空指针,所以在使用指针时,必须要对指针进行非空判断。

NULL和nullptr的替换问题:

我在书写指针的非空判断时回想起以前老师书写的时候有nullptr也有NULL,于是对这两个东西我做了一些简单的了解:

在c语言中,nullptr的存在实际上是为了替代NULL的,nullptr是在C++11版本中新加入的关键字,它的出现是为了解决NULL表示空指针在C++中的二义性问题。二义性也就是结果的含糊不定,这对于以严谨而闻名的编程而言自然是不行的。

这里我对于NULL的二义性问题有两个理解:

第一个理解:

今天早上阅读了《C和指针》中的6.6NULL指针,里面提到:NULL指针的概念是非常有用的,因为它给了你一种方法,就是某个特定的指针目前并未指向任何东西,例如,一个用于在数组中查找某个特定值的函数可能返回一个指向查找到的元素的指针。如果该数组不包括指定条件的值,函数就返回一个NULL指针。这个技巧允许返回值传达两个不同返回值的信息。第一个:有没有找到元素?第二个:如果找到,它是哪个元素?

这是NULL的第一个二义性问题,因为它传达了两个信息,就是找到没有?找到了在哪?但是这个问题并不是建议使用nullptr来替换NULL的原因,它只是违背了软件工程的原则。

第二个理解:

在C语言中,NULL通常被定义为:#define NULL ((void *)0)

这样来看,这个语句本质上就是一个宏,里面是void *类型的指针,也就是空指针。

在C++语言中,本身在语言诞生的时候,就极力的避免产生宏,所以这时就有了问题:

NULL的二义性的体现:

我们看看C++中对于NULL的定义:

#if defined(__cplusplus)
# define NULL 0 /* C++中使用0作为NULL的值 */
#else
# define NULL ((void *)0) /* C中使用((void *)0)作为NULL的值 */
#endif

C++语言可以看做是对C语言的延伸和扩展,这里可以看到,NULL的定义有两种,一种直接定义为0,这时C++中的定义,上文中提到了C中使用空指针作为NULL的值。

下面有两个函数:

void fun(int ){};//形参为int类型
void fun(int *){};//形参为int *类型

C++中把NULL直接定义为0,所以fun(NULL)就会去调用void fun(int )函数,我们原本是要去调用fun(int *)这个函数的,所以这时候就产生了歧义。

所以,在2011年发布的C版本中出现了nullptr:

如果我们使用nullptr,也就是fun(nullptr),就会调用fun(int *)函数了,完美的解决了这一问题。

在这里补充:nullptr实际上是有类型的,就是nullptr_t

总结:如果你的编译器支持nullptr的话,尽量选择去使用nullptr而不是NULL。

在更改NULL为nullptr时我遇到的问题:

NULL替换为nullptr编译器报错:

使用上文数组元素调换的程序当作例子:

图1-1

我在执行指针的非空判断时,将所有的NULL均替换为了nullptr,但是在编译运行的时候编译器报错了,这是报错的语句:

error: use of undeclared identifier 'nullptr';

这句话在翻译过来就是使用了未定义的关键字nullptr,于是我在网上查找解决方案,绝大多数的文章都在说,nullptr是c11版本中新加入的关键字,应该在vscode中将编译时的C版本从默认(default)如图在设置中搜索“cppstandard”,选中C++11即可完成修改:

图1-2

但是在修改完版本后依然报错。

这时我看到我在替换nullptr编译器出来的提示性信息:nullptr(c++关键字)也就是我在图1-1中使用紫色箭头标中的提示,于是我又添加了一个头文件:

#include<iostream>

这个头文件包含了C++标准的输入输出,也就是编译器把头文件iostream中的所有内容全部复制到#include中然后再进行编译操作,但是注意这个头文件后面是没有.h后缀的。

如图我进行C++头文件的添加:

问题解决,程序运行成功!

#include<stdio.h>
#include<iostream>

从程序的运行结果来看,这两个头文件是可以共存的,问题得到了解决。

C语言-7月22日- NULL和nullptr的深入了解以及VScode对nullptr语句报错问题的解决相关推荐

  1. AI:2020年6月22日北京智源大会演讲分享之09:40-10:10Mari 教授《基于显式上下文表征的语言处理》、10:10-10:40周明教授《多语言及多模态任务中的预训练模型》

    AI:2020年6月22日北京智源大会演讲分享之09:40-10:10Mari 教授<基于显式上下文表征的语言处理>.10:10-10:40周明教授<多语言及多模态任务中的预训练模型 ...

  2. AI:2020年6月22日北京智源大会演讲分享之《语音与自然语言处理》09:10-09:40 Christopher 教授《基于深度上下文词表征的语言结构的发现》

    AI:2020年6月22日北京智源大会演讲分享之<语音与自然语言处理>09:10-09:40 Christopher 教授<基于深度上下文词表征的语言结构的发现> 导读:首先感 ...

  3. 2021年4月22日 阿里供应链Java开发实习面试(三面)(含总结)

    title: 2021年4月22日 阿里供应链Java开发实习面试(三面) tags: 面经 2021年4月22日 阿里供应链Java开发实习面试(三面) 上来就手撕一道代码--输入一个数,然后顺时针 ...

  4. 分享Silverlight/WPF/Windows Phone/HTML5一周学习导读(4月16日-4月22日)

    分享Silverlight/WPF/Windows Phone/HTML5一周学习导读(4月16日-4月22日) 本周Silverlight学习资源更新 银光中国网友原创:Silverlight中获取 ...

  5. 9月22日培训日记(上)

    首先检查昨天的作业,了解学员对昨天讲解知识的掌握情况. (1)根据马献忠完成的BasicDataSourceFactory.createDataSource(Properties properties ...

  6. 【目标一】2019年9月15日 - 2019年9月22日晚 --- 周计划

    2019年9月15日 - 2019年9月22日晚 --- 周计划 工作日作息时间 周末或者节假日作息时间(如果没有活动 或者 不用加班的话) 心若向暖,何处不阳光:心若向阳,便何处不花开 \^_\^ ...

  7. 鲸探发布点评:7月22日发售观德亭、全家福、龙凤呈祥熏数字藏品

    今天鲸探将发3款藏品:<观德亭>.<全家福>.<龙凤呈祥熏>数字藏品.发行价格18,发行数量10000*3. 冯有进,1953年出生,安徽黄山人.第一批国家级非物质 ...

  8. 【历史上的今天】8 月 22 日:改变世界的程序员们

    整理 | 王启隆 透过「历史上的今天」,从过去看未来,从现在亦可以改变未来. 今天是周日,2021年 8 月 22 日.历史上的今天,Masatoshi Shima出生,他和 英特尔(Intel) 合 ...

  9. 【历史上的今天】10 月 22 日:微软发布 Windows 7;谷歌推出广告平台;静电复印机雏形

    整理 | 王启隆 透过「历史上的今天」,从过去看未来,从现在亦可以改变未来. 今天是 2022 年 10 月 22 日,在 1994 年的今天,中国公用数字数据网(CHINADDN)正式建成开通,为如 ...

最新文章

  1. ubuntu 16.04 多个python版本切换
  2. C++知识点53——虚继承
  3. POJ 1170 Shoping Offers(IOI 95)
  4. 使用postman传递参数时报错:Content type ‘multipart/form-data;boundary=--(略)
  5. 给你的执行力马上充值
  6. Python3小知识
  7. 测试基础-06-测试计划编写
  8. Cassandra Wiki Login JmxSecurity
  9. 贪吃蛇c语言源代码彩色版,贪吃蛇C语言源代码
  10. Python小白的数学建模课-11.偏微分方程数值解法
  11. word两页并排怎么变成单页排列
  12. OOALV进阶版:实现一个屏幕下展示多个ALV,跳转网页
  13. ubuntu18设置屏幕旋转_[Android6.0][MTK6737] 设置屏幕旋转 270 度
  14. 2020 中南大学研究生招生夏令营机试题(1252~1256)
  15. 各种标点符号的英文怎么念
  16. 群晖存储空间不足-处理方案一
  17. 中国互联网的沧海桑田
  18. 批处理(.bat)文件
  19. mysql 修改分区名_修改数据库分区表分区名和所属表空间,限于Oracle10g
  20. 易语言大漠多线程启动方式许可证

热门文章

  1. nvl2可以套公式吗 oracle_Oracle的nvl函数和nvl2函数
  2. JSON 与 BSON 区别
  3. a标签常用属性——你是否都用过?
  4. html a标签怎样设置宽高,a标签如何设置高度和宽度
  5. PHP Think PHP 5 实现短信发送 此API为短信宝
  6. 239_macroexp--cons功能以及实现分析
  7. [class^='icon-'], [class*=' icon-']
  8. 笔记本电脑计算机没了,如果笔记本电脑很长时间没有关闭,它将对笔记本计算机产生什么影响?看了很久的经验...
  9. pytorch中自加(+=)与普通加的区别,及原位操作
  10. (转)更换镜像rootvg卷组中的硬盘