在C语言中,各种零值之间似乎存在差异——NULL、NUL和0。
我知道ASCII字符“0”的值为48或0x30。
NULL指针通常定义为:
#define NULL 0
Or
#define NULL (void *)0
此外,还有NUL字符“\0”,它的值似乎也是0。
是否存在这三个值不能相等的情况?
在64位系统上也是这样吗?
在C语言中,各种零值之间似乎存在差异——NULL、NUL和0。
我知道ASCII字符“0”的值为48或0x30。
NULL指针通常定义为:
#define NULL 0
Or
#define NULL (void *)0
此外,还有NUL字符“\0”,它的值似乎也是0。
是否存在这三个值不能相等的情况?
在64位系统上也是这样吗?
当前回答
一个1 - l的NUL,它结束一个字符串。
一个2l的NULL不指向任何东西。
我要赌一只金牛
没有3l null。
你如何处理NUL?
其他回答
似乎很多人误解了NULL、'\0'和0之间的区别。为了避免重复之前说过的话,我来解释一下:
int类型的值为0的常量表达式,或该类型的表达式,转换为void *类型是空指针常量,如果转换为指针则成为空指针。该标准保证与指向任何对象或函数的任何指针的比较不相等。
NULL是一个宏,定义为空指针常量。
\0是一个用于表示空字符的结构,用于结束字符串。
空字符是一个所有位都设置为0的字节。
这三者在不同的上下文中定义了0的含义。
指针上下文-使用NULL,表示指针的值为0,与它是32位还是64位无关(一种情况是4字节,另一种情况是8字节的零)。 string context -表示数字0的字符的十六进制值为0x30,而NUL字符的十六进制值为0x00(用于终止字符串)。
当你查看内存时,这三个总是不同的:
NULL - 0x00000000 or 0x00000000'00000000 (32 vs 64 bit)
NUL - 0x00 or 0x0000 (ascii vs 2byte unicode)
'0' - 0x20
我希望这能解释清楚。
一个1 - l的NUL,它结束一个字符串。
一个2l的NULL不指向任何东西。
我要赌一只金牛
没有3l null。
你如何处理NUL?
注意:这个答案适用于C语言,而不是c++。
空指针
整数常量字面值0有不同的含义,这取决于它所使用的上下文。在所有情况下,它仍然是一个值为0的整数常数,只是用不同的方式描述它。
如果将一个指针与常量字面值0进行比较,那么这将检查该指针是否为空指针。这个0被称为空指针常量。C标准定义了转换为void *类型的0既是一个空指针,也是一个空指针常量。
此外,为了提高可读性,在头文件stddef.h中提供了宏NULL。取决于你的编译器,它可能是#undef NULL,并重新定义它的一些古怪的东西。
因此,这里有一些检查空指针的有效方法:
if (pointer == NULL)
NULL被定义为比较等于空指针。它的实现定义了NULL的实际定义,只要它是一个有效的空指针常量。
if (pointer == 0)
0是空指针常量的另一种表示形式。
if (!pointer)
这个if语句隐式检查“is not 0”,因此我们将其反转为“is 0”。
以下是检查空指针的无效方法:
int mynull = 0;
<some code>
if (pointer == mynull)
对于编译器来说,这不是一个空指针的检查,而是两个变量的相等性检查。如果mynull在代码中从未改变,并且编译器优化常量将0折叠到if语句中,这可能会起作用,但这并不能保证,编译器必须根据C标准产生至少一个诊断消息(警告或错误)。
注意,C语言中空指针的值与底层体系结构无关。如果底层体系结构有一个定义为地址0xDEADBEEF的空指针值,那么就由编译器来整理这个混乱。
因此,即使在这个有趣的架构上,以下方法仍然是检查空指针的有效方法:
if (!pointer)
if (pointer == NULL)
if (pointer == 0)
以下是检查空指针的无效方法:
#define MYNULL (void *) 0xDEADBEEF
if (pointer == MYNULL)
if (pointer == 0xDEADBEEF)
因为这些被编译器视为正常的比较。
空字符
'\0'被定义为空字符——即所有位都设置为零的字符。'\0'是一个整数常量(像所有字符字面值一样),在本例中值为0。因此,'\0'完全等同于一个未修饰的0整数常量——唯一的区别是它向人类读者传达的意图(“我将此用作空字符。”)。
“\0”与指针无关。然而,你可能会看到类似于下面代码的东西:
if (!*char_pointer)
检查char指针是否指向空字符。
if (*char_pointer)
检查char指针是否指向非空字符。
不要把它们和空指针搞混了。只是因为位表示是相同的,这允许一些方便的交叉情况,它们实际上不是同一件事。
参考文献
更多信息请参见comp.lang.c常见问题中的问题5.3。 有关C标准,请参阅此pdf。请参阅第6.3.2.3节第3段的“指针”。
NULL, ' \0 '和0之间的区别是什么
“空字符(NUL)”是最容易排除的。'\0'是字符字面量。 在C语言中,它被实现为int,因此,它与0相同,它是INT_TYPE_SIZE。在c++中,字符字面值被实现为char,即1字节。这通常不同于NULL或0。
接下来,NULL是一个指针值,指定变量不指向任何地址空间。撇开它通常实现为零的事实不谈,它必须能够表达体系结构的完整地址空间。因此,在32位体系结构上,NULL(可能)是4字节的,而在64位体系结构上是8字节的。这取决于C的实现。
最后,字面值0的类型为int,大小为INT_TYPE_SIZE。INT_TYPE_SIZE的默认值可能根据体系结构而不同。
苹果写道:
Mac OS X使用的64位数据模型被称为“LP64”。这是Sun和SGI的其他64位UNIX系统以及64位Linux所使用的通用数据模型。LP64数据模型定义的基元类型如下: int是32位的 long是64位的 long-long也是64位的 指针是64位的
维基百科64位:
微软的vc++编译器使用LLP64模型。
64-bit data models
Data model short int long long long pointers Sample operating systems
LLP64 16 32 32 64 64 Microsoft Win64 (X64/IA64)
LP64 16 32 64 64 64 Most Unix and Unix-like systems (Solaris, Linux, etc.)
ILP64 16 64 64 64 64 HAL
SILP64 64 64 64 64 64 ?
编辑: 增加了更多的字符文字。
#include <stdio.h>
int main(void) {
printf("%d", sizeof('\0'));
return 0;
}
上面的代码在gcc上返回4,在g++上返回1。