其他
空指针,段错误,这场面试我栽倒在这里了!
The following article is from 技术让梦想更伟大 Author 李肖遥
面试官:满头的汗的,来面试的路一定很远吧?
还好还好,骑车不到俩小时
面试官:来先喝杯水,咱们面试不急,边喝边聊
哇,谢谢您啦,咕隆咕隆喝下半杯
面试官:那咱们开始吧,看你项目做的还不少啊,不错不错,咱们随便聊聊。
哇,“这面试官还不错,感觉有戏”
面试官:说说空指针NULL是本质什么,与0一样吗
嗯嗯,这个,NULL不就是0吗?
面试官:你确定是吗,面带微笑,淡定的眼神......
嗯嗯,应该是吧,,,不是吧,汗又开始冒起了来了......
面试官:嗯嗯,了解了,不急慢慢喝水,我先上个厕所。
水的滋润与口水相互交织,骑车两小时,面试3分钟,这次我栽在这里了。
NULL的标准定义
#ifdef _cplusplus
#define NULL 0 // 这里对应C++的情况
#else
#define NULL (void *)0 // 这里对应C语言的情况
#endif
在 C/C++ 中的区别
在 C 语言中,C 中的“标准”写法,NULL 被替换为一个 void* 类型的指针右值,值等于0;由于是 void* 类型,可以隐式转化为其它类型的指针。在 C++ 中,void* 无法自由隐式转换为其它类型的指针,而字面量 0 可以隐式转换为指针类型。NULL 的本质是什么
我们从指针,空指针,空指针常量以及指向的内存说起。
从指针角度来看:
我们看以下定义,p 是一个函数内的局部变量,则 p 的值是随机的,也就是说 p 是一个野指针。{
int *p;
...
}
{
int *p = NULL;
...
}
什么是空指针(null pointer)?
如果将空指针常量转换为指针类型,则保证生成的指针(称为空指针)将不相等的值与指向任何对象或函数的指针进行比较。定义 char *p=0 后,在之后 p 的任何一种赋值操作之后,p 都成为一个空指针,即 p 不指向任何实际的对象或者函数。反过来说,任何对象或者函数的地址都不可能是空指针。什么是空指针常量(null pointer constant)?
值为 0 的整数常量表达式,或强制转换为 void * 类型的表达式,称为空指针常量。空指针(null pointer)指向了哪里的内存?
这里标准没有定义,取决于系统的实现。我们常见的空指针一般指向 0x00000000 地址,即空指针的内部用全 0x00000000 来表示,也有一些系统用一些特殊的地址值或者特殊的方式表示空指针。在我们实际写代码时,关键点在于判断哪个是空指针。NULL 有什么作用?
在大部分的 CPU 中,内存的 0x00000000 地址处都不是可以随便访问的,所以野指针指向了这个区域可以保证野指针有个安家之所,否则会发生段错误。当你尝试访问的时候会阻止你,但是有些地址不是只读的,如果一个指针指向了这个地址,你又在不经意间修改了它,可能会导致一些重要的文件被修改,所以指针初始化成 NULL 是有必要的。注意不要混用 '\0' 和 '0' 和 0 和 NULL。
'\0' 是一个转义字符,他对应的 ASCII 编码值是 0,本质就是 0;常用于表示字符串的结尾标志,以判断字符串有没有到头。 '0' 是一个字符,他对应的 ASCII 编码值是48,本质是48。 0 是一个 int 类型的数字,本质就是 0。 NULL 是一个表达式,是强制类型转换为 void * 类型的 0,一般用来比较指针是否是一个野指针。
NULL是不是0
NULL 就是 0?
我们先来看以下代码:#include<stdio.h>
int main()
{
int *p=NULL;
printf("%s",p);
}
NULL 不是 0?
如果一个指针被赋予 NULL,相当于这个指针执行了 0x00000000 这个逻辑地址,但是在 C 语言中 0x0000 这个逻辑地址用户是不能使用的,所以当你试图取一个指向了 NULL 的指针的内容时,就会提示段错误,测试一下代码如下://来源:技术让梦想更伟大
//作者:李肖遥
#include<stdio.h>
int main()
{
int *node = NULL;
int p = 0;
p = *node;
printf("%d\n",p);
return 0;
}
//来源:技术让梦想更伟大
//作者:李肖遥
#include <stdio.h>
void vPassByFun(int *node)
{
static int N = 1024;
node = &N;
}
int main()
{
int *node = NULL;
int p = 0;
vPassByFun(node);
p = *node;
printf("%d\n",p);
return 0;
}
//来源:技术让梦想更伟大
//作者:李肖遥
#include <stdio.h>
void vPassByFun(int ** node)
{
static int N = 1024;
*node=&N;
}
int main()
{
int *node = NULL;
int p = 0;
vPassByFun(&node);
p = *node;
printf("%d\n",p);
return 0;
}
最后
编码过程中,我们需要对自己的指针负责,往往导致 bug 出现或者找不到问题所在地的就是这种细节。最后,原创不易,希望能够改正文章的错误,多提意见留言,谢谢。