C语言中的"NULL"到底是什么?又不是什么?有什么用?怎么用?

这个问题其实困扰我很久了,我问很多人"NULL"是什么?有啥用?

大多数人的回答是:"NULL就是系统定义特殊的0,把你初始化的指针指向它,可以防止“野指针”的恶果。"

今天碰到一个C语言的笔试题,还是一道不错的题~~~

Exp 1:

[cpp]  view plain copy
  1. #include <stdio.h>  
  2.   
  3. void fun(int *node)  
  4. {  
  5.     static int N=100;  
  6.     node=&N;  
  7. }  
  8. int main()  
  9. {  
  10.     int *node=NULL;  
  11.     int a=0;  
  12.     fun(node);  
  13.     a=*node;  
  14.     printf("%d\n",a);  
  15.       
  16.     return 0;  
  17.   
  18. }  
请回答,以上这题的输出结果啥?

从结果中,这题可以区别出对C语言掌握的几个程度。那结果是:100?0?段错误退出?哪一句导致的?为什么?


认为是第一个结果人其实是被static这个关键词欺骗的,但是static是对N的修饰,表示对N的改变不会在fun函数的‘}’之后被释放掉~~~还有一个点就是:C语言的函数永远是值传递(除了数组,呵呵~~~),所以你想改变指针的指向(地址值),就必须传递指针的指针,除非你用return~~~

认为是第二个结果的人掌握了第一个结果的点,并且知道在C语言里是那样定义NULL的:

[cpp]  view plain copy
  1. #undef NULL  
  2. #if defined(__cplusplus)  
  3. #define NULL 0  
  4. #else  
  5. #define NULL ((void *)0)  
  6. #endif  
但是gcc下发现却是段错误退出了~~~

问题在这句:

[cpp]  view plain copy
  1. a=*node;   
[cpp]  view plain copy
  1. /*对node进行*运算,node此时木有改变的,还是(void *)0指针~~~所以段错误就出来,当然你可以读取NULL本身的值,即0,但是读取它指向的值,那是非法的,会引发段错误(貌似这种指针的错误还有:操作系统限制用户访问的地址空间,内存木有分到的地址空间(几百KB的嵌入式系统中普遍存在),再加这种就有三种,当然野指针也可能乱指到一般用户合法的地址,然后就乱改,然后就失控了~~~)*/  


NULL是个好东西,给一出生的指针一个安分的家~~~


ps:我一开始就以为是0,功力不深啊~~~修炼,修炼~~~


Exp 2:

[cpp]  view plain copy
  1. #include <stdio.h>  
  2.   
  3. int main(...)  
  4. {  
  5.     int *iPtr1 = NULL;  
  6.     int *iPtr2 = 0;  
  7.     //error: invalid conversion from `int' to `int*'  
  8.     int *iPtr3 = 1;  
  9.   
  10.     //error: invalid conversion from `void*' to `int*'  
  11.     int *iPtr4 = ((void* )0);  
  12.       
  13.     return 0;  
  14. }  
好了,前两种初始化定义是正确的,第一个错误表明0是一个比较特殊的数字,应该是编译器的特殊照顾,但是第二个错误不是符合NULL的第二个宏定义么?但是从指针类型来说却是有问题的,所以咋回事呢?难道编译器对NULL这个关键字做了特殊照顾?

Form 《Understanding and Using C Pointers》

PS:书中也貌似木有解释这个问题。


To Be Continued~~~

  • 1
    点赞
  • 0
    评论
  • 1
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

表情包
插入表情
评论将由博主筛选后显示,对所有人可见 | 还能输入1000个字符
©️2021 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值