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

本文详细解析C语言中NULL指针的概念及其用途,通过实例探讨了NULL指针在指针操作中的行为及可能导致的错误情况,帮助读者深化对C语言指针的理解。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

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

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

Exp 1:

#include <stdio.h>

void fun(int *node)
{
    static int N=100;
    node=&N;
}
int main()
{
    int *node=NULL;
    int a=0;
    fun(node);
    a=*node;
    printf("%d\n",a);
    
    return 0;

}
请回答,以上这题的输出结果啥?

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


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

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

#undef NULL
#if defined(__cplusplus)
#define NULL 0
#else
#define NULL ((void *)0)
#endif
但是gcc下发现却是段错误退出了~~~

问题在这句:

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


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


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


Exp 2:

#include <stdio.h>

int main(...)
{
    int *iPtr1 = NULL;
    int *iPtr2 = 0;
    //error: invalid conversion from `int' to `int*'
    int *iPtr3 = 1;

    //error: invalid conversion from `void*' to `int*'
    int *iPtr4 = ((void* )0);
    
    return 0;
}
好了,前两种初始化定义是正确的,第一个错误表明0是一个比较特殊的数字,应该是编译器的特殊照顾,但是第二个错误不是符合NULL的第二个宏定义么?但是从指针类型来说却是有问题的,所以咋回事呢?难道编译器对NULL这个关键字做了特殊照顾?

Form 《Understanding and Using C Pointers》

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


To Be Continued~~~



 

<think>嗯,用户问的是C语言中“no”是什么意思。首先,我需要确定用户提到的“no”具体出现在什么上下文中。因为C语言本身的关键字和保留字里并没有“no”这个词。可能的情况有几个: 1. **变量或函数名**:用户可能在代码中看到有人用“no”作为变量名或函数名,这时候它只是一个自定义的标识符,没有特殊含义。需要根据代码的上下文来理解它的作用。 2. **宏定义**:有时候程序员会用#define来定义宏,比如`#define NO 0`,这样在代码中出现的NO就会被替换成0。这种情况下,“NO”可能代表某个特定的值,但这也是项目或代码库特定的,不是C语言的标准部分。 3. **拼写错误或误解**:用户可能原本想问的是“NULL”,这在C语言中是一个空指针常量,用来表示指针不指向任何有效的内存地址。或者可能是其他类似的关键字,比如“not”相关的逻辑运算符,但C语言中使用的是“!”而不是“no”。 接下来,我应该考虑用户可能的背景。如果用户是初学者,可能会混淆一些术语或者拼写错误。比如,他们可能想了解逻辑非操作符“!”,但误写成了“no”。或者他们可能在其他地方看到了“NO”被用作某个常量,比如错误代码中的枚举值。 另外,需要检查是否有其他可能性,比如某些库或框架中的特定定义。例如,某些嵌入式系统或第三方库可能会定义自己的常量,如NO_ERROR或者类似的,但这也是特定于环境的,并非C语言标准的一部分。 总结来说,用户的问题可能是因为在代码中遇到了“no”这个标识符,想知道其作用,但由于C语言本身没有这个关键字,所以需要更多的上下文来解释。或者可能存在拼写错误,用户实际想问的是其他类似的关键字或概念,比如“NULL”、“!”,或者预处理指令中的“#ifndef”等。 需要进一步询问用户是否有具体的代码示例,或者更详细的上下文,以便提供更准确的解答。同时,可以简要解释常见的可能性,帮助用户理解可能的情况,并引导他们提供更多信息以便进一步帮助。</think>在C语言中,**`no` 本身并不是关键字或标准库中的保留标识符**。它的含义完全取决于具体的代码上下文,可能有以下几种情况: --- ### 1. **自定义标识符(变量/函数名)** - 如果代码中出现了 `no`,它可能是程序员自定义的变量名、函数名或宏定义。例如: ```c int no = 10; // "no" 只是一个整型变量 void print_no() { ... } // 自定义函数名 ``` - 此时需要结合代码逻辑理解它的作用。 --- ### 2. **宏定义(#define)** - 可能是通过 `#define` 定义的宏,例如: ```c #define NO 0 // 将 NO 定义为 0 #define NO ! // 少数情况下可能表示逻辑非(但通常用 "!") ``` - 这类定义是项目特定的,需查看代码中的宏定义部分。 --- ### 3. **拼写错误或误解** - **`NULL`**:C语言中表示空指针的常量,用于指针不指向任何有效内存时: ```c int *ptr = NULL; ``` - **逻辑非运算符 `!`**:若用户实际想问的是“逻辑非”(如 `if (!condition)`),C语言中使用 `!` 而非 `no`。 - **预处理指令 `#ifndef`**:用于条件编译,检查是否未定义某个宏: ```c #ifndef HEADER_H #define HEADER_H // 头文件内容 #endif ``` --- ### 4. **第三方库或框架中的定义** - 某些库可能用 `NO` 表示状态(如错误码): ```c enum Status { YES, NO }; // 自定义枚举 ``` --- ### 总结 如果遇到 `no`,请检查代码中是否有以下内容: 1. 变量或函数的定义(如 `int no;`)。 2. 宏定义(如 `#define NO ...`)。 3. 是否混淆了 `NULL`、`!` 或 `#ifndef` 等关键字。 若提供更多代码上下文,可以进一步分析其具体用途!
评论 17
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值