c语言里NULL的理解

NULL一看名字就知道为空,什么为空呢,而且全是大写。是不是意味着是个宏定义呢?如果想到这里,我相信你离真理不远了。

有些人为什么犯错?因为只看到了NULL这四个字母而已,没有看到事物的本质,老师在课堂上也只是说空指针,空字符串。。这样只会陷入无止境的误区。如果我这样定义:

#define NULL 0

你是不是又该纠结了呢?

正确的做法是把它当作一个宏,不管如何变化,来展开看看就知道了。

在C语言的头文件stddef.h中,NULL的定义如下:

#define NULL

#define __cplusplus  //如果定义了__cplusplus表示是c++程序

#define NULL 0

#else

#define NULL ((void *)0)

#endif

#endif

#interface NULL 0

所以,c语言里NULL的本质是(void *)0。

这里一开始就犯了个错,强制转换的意义是什么??感谢朱老师物联网大课堂的朱老师以及群里的朋友们的激烈讨论。以下内容截取自我们的讨论。

((void *)0)  本质上是将数字0强制转换为(void *)。0其实就是地址,(void *)只是说我们认为0这个地址中存储的类型是void *,也就是说0这个地址中存储的类型是void的,也就是当前不知道还未指定的.

0 地址是虚拟地址  还是物理地址?

不管是虚拟还是物理地址,就是当前环境的0地址。

要理解强制类型转换的本质

0还是0,永远是0,表示的永远是0这个内存地址;前面的类型,只是告诉我们我们认为0这个地址中装了什么

首先 这里的数字0  就是表示地址0???

不能讲某个数字直接强制转化为指针吗

举个例子就可以了:

#define GPJ0CON (unsigned int *)0x20008000

如果是需要将一个数字强制转换为指针,是不是可以这样写呢 int * &2, 是不是强制讲2转化为指针类型了呢

这样啊   (unsigned int *)0x2

char i=2; 间接讲2转换为int 指针。是不是这样写int * &i

char i = 2;之后 编译器会给i变量分配一个地址,&i  就是取i变量的地址。变量定义后就会分配地址。

我说的0,你这里写的2本身这个数字就是表示地址,而你的理解是2是值,这个值存在一个变量中,所以想通过&2去取2的地址,这个是错误的。因为只有变量才有地址,2只是个数字是没有地址的。

而单纯的数字本身就是地址。

是的,在这里确实是这样,因为这个数字我们要把它强制类型转化成指针,所以这个数字就是地址

C语言里有很多东西都是这种,规则只是讲了法律,但是实际应用中有很少常用技巧、或者衍生出来的用法,都没有提及,这也是我们的C高级课程中需要补充的。

因为只有变量才有地址,2只是个数字是没有地址的.因为这个数字我们要把它强制类型转化成指针,所以这个数字就是地址

C语言中就通过类型来表示这个单元中存的什么玩意,譬如(int)0就表示0地址中存的是int型的数;譬如你(int *)0就表示0地址中存的是个地址,这个地址指向的单元是int型数

NULL只是一个概念,叫作空值,其值本身没有任何含义,可以用0代替,也可以用1,...代替,只要这些值不会与系统实际的有效地址冲突即可。

因此,本人在此再次强调,不要自作聪明地认为NULL就是0,要判断的时候还是老老实实地与NULL做比较,别想当然地用什么!ptr之类的写法,因为在某个特定环境下,NULL可能不是0,而系

统函数返回的是NULL不是0,那时,你的函数就会出现莫名其妙的错误。所以,养成良好的习惯是非常重要的。

从这里学到了一点  如果看到了一个宏不会用   那么最好的办法 不是去看别人的解释  而是展开它,看它的最终展开形式。

总结如下:

c语言中NULL表示内存位置0,NULL((void *)0)指针并不指向任何对象。因此除非是用于赋值或比较运算,出于其他任何目的使用NULL指针都是非法的。

注意:在ASCII码的第一个字符是NULL,它的数值是0,占用1字节;C语言把它作为字符串的最后一个字符,以表示字符串到此结束."\0"

接下来:总结下NULL具体用在哪些场合。

第一:指针初始化(对应于上面的赋值)。

例如 int *x = NULL;

第二:函数返回是否成功判断(对应于做比较运算)。

当函数返回值为指针时,判断函数是否返回成功。举例如下:

FILE * pFile;
pFile = fopen ("myfile.txt" , "r");
if (pFile == NULL) printf("open error");

第三:判断字符串是否为空字符串(对应于做比较运算)。

if(str==NULL)或者if(str[0]==‘\0‘)
就是空

时间: 2024-12-22 22:08:40

c语言里NULL的理解的相关文章

const分别在C和C++语言里的含义和实现机制

const的含义        简单地说:const在c语言中表示只读的变量,而在c++语言中表示常量. C语言 const是constant的缩写,是恒定不变的意思,也翻译为常量,但是很多人都认为被const修饰的值都是常量,其实这是不精确的.因为,精确来说应该是只读的变量,其值在编译的时候不能被使用,因为编译器在编译的时候不知道其存储的内容.或许当初这个关键字应该被替换为readonly. C语言中const定义的变量只是给出了对应的内存地址,而不是像#define一样给出的是立即数,所以,

[原创]C语言里为何会有“2+2=5”的结果

原文链接:C语言里为何会有“2+2=5”的结果 写这篇原创文章是因为看到了极客中的一篇文章<有趣各种编程语言实现2+2=5>,其中C语言是这样实现的: 1 int main() { 2 char __func_version__[] = “5″; // For source control 3 char b[]=”2″, a=2; 4 printf(“%d + %s = %s\n”, a, b, a+b); 5 return 0; 6 } 有些童鞋可能会说,这不是偷换概念吗,拿字符串和int相

C语言里全局变量管理

C语言里信息封装比較弱,仅仅有静态变量的文件作用域. 假设不加约束.非常easy造成全局变量满天飞. 假设定义一个全局结构体.把全局变量都放到这个GlobleVariate里,应该好管一些,至少比裸奔文雅一点. 更进一步,每一个模块定义自己的结构体.把模块公共变量放到结构体里.这样把GlobleVariate拆成多个小结构体,会更文雅一些. 大概的伪代码是以下这个样子. struct GlobleVariate { struct ModuleVariate1: struct ModuleVari

C语言里为何会有“2+2=5”的结果

写这篇原创文章是因为看到了极客中的一篇文章<有趣各种编程语言实现2+2=5>,其中C语言是这样实现的: int main() { char __func_version__[] = "5″; // For source control char b[]="2″, a=2; printf("%d + %s = %s\n", a, b, a+b); return 0; } 有些童鞋可能会说,这不是偷换概念吗,拿字符串和int相加,是滴,但在这里请这些童鞋暂且

嵌入式C语言里的土豪们之除法与移位

土豪这个词用在接下来要出场的C语言再合适不过了.他们在嵌入式C语言里占尽了奢华,但是毕竟我们更需要一个节约型的微生态环境.在这里简单给大家分析一下嵌入式C语言编程时用到的除法与移位. 本文引用地址:http://www.eepw.com.cn/article/182359.htm 除法土豪 除法在嵌入式微处理器里可算是一个消耗大户,复杂的实现方式不仅占用了大师宝贵的计算时间而且精度有限情况下占用了大片的RAM.因此,常常在各类文章里看到,编程人员应该使用右移运算来代替除法.这个右移方法没有问题,

Django与SQL语言中——NULL与空字符串的区别

SQL有指定空值的独特方式,它把空值叫做NULL. Null在数据库中表示 不知道的数据,主要有3种意思: 1)知道数据存在,但不知道具体值. 2)不知道数据是否存在. 3)数据不存在. 在SQL中, NULL的值不同于空字符串,就像Python中None不同于空字符串("")一样.这意味着某个字符型字段(如VARCHAR)的值不可能同时包含NULL和空字符串. 这会引起不必要的歧义或疑惑. 为什么这条记录有个NULL,而那条记录却有个空字符串? 它们之间有区别,还是数据输入不一致?

理解Python语言里的异常(Exception)

Exception is as a sort of structured "super go to".异常是一种结构化的"超级goto". 作为一个数十年如一日地钟爱C语言的程序员(因为C程序员需要记忆的关键字很少,而且可以很惬意地玩内存),对于高级语言如Python里的异常(Exception)一直不甚理解,尤其是其实现机理.但读了<Learning Python>一书中上面这句话(尤其是goto关键字)后,忽然豁然开朗. 如果用C语言编写一个鲁棒性良

C语言02基础深入理解(二)

指针基础 变量回顾 既然程序中的变量只是一段存储空间的别名 , 那么是不 是必须通过这个别名才能使用这段存储空间 ? 指针本质 ?  指针在本质上也是一个变量 ?  指针需要占用一定的内存空间 ?  指针用于保存内存地址的值 * 号的意义 ?  在指针声明时 ,* 号表示所声明的变量为指针 ?  在指针使用时 ,*  号表示取指针所指向的内存空间中的值 // 指针声明 : int i = 0; int j = 0; int* p = &i; // 取值 : j = *p; p: 0xAABBCC

C语言里字符串的解析

原文网摘:http://www.cnblogs.com/yi-meng/p/3620244.html#undefined 根据给定的字符串,按照一定规则解析字符串,卡住好几次,这次做个笔记,以供参考 函数名称:   strtok 函数原型:   char *strtok(char *s1, const char *s2) 函数功能:   分解s1字符串为用特定分隔符分隔的多个字符串(一般用于将英文句分解为单词) 函数返回:   字符串s1中首次出现s2中的字符前的子字符串指针 参数说明:   s