在C中,似乎有零各个值之间的差- NULL
,NUL
和0
.
我知道ASCII字符的'0'
计算结果为48
或0x30
.
该NULL
指针通常定义为:
#define NULL 0
Run Code Online (Sandbox Code Playgroud)
要么
#define NULL (void *)0
Run Code Online (Sandbox Code Playgroud)
另外,也有似乎评价的NUL
人物.'\0'
0
是否有时候这三个值不相等?
这在64位系统上也是如此吗?
And*_*ton 333
注意:这个答案适用于C语言,而不是C++.
整数常量字面值0
具有不同的含义,具体取决于使用它的上下文.在所有情况下,它仍然是一个带有值的整数常量0
,它只是以不同的方式描述.
如果将指针与常量文字进行比较0
,则检查指针是否为空指针.这0
随后被称为一个空指针常数.C标准定义0
对类型的强制转换void *
既是空指针又是空指针常量.
此外,为了帮助提高可读性,宏NULL
在头文件中提供stddef.h
.根据您的编译器,可能会将其#undef NULL
重新定义为古怪的东西.
因此,这里有一些检查空指针的有效方法:
if (pointer == NULL)
Run Code Online (Sandbox Code Playgroud)
NULL
被定义为比较等于空指针.它是实现定义的实际定义NULL
是什么,只要它是一个有效的空指针常量.
if (pointer == 0)
Run Code Online (Sandbox Code Playgroud)
0
是空指针常量的另一种表示.
if (!pointer)
Run Code Online (Sandbox Code Playgroud)
该if
语句隐式检查"不是0",因此我们将其反转为"是0".
以下是检查空指针的INVALID方法:
int mynull = 0;
<some code>
if (pointer == mynull)
Run Code Online (Sandbox Code Playgroud)
对于编译器,这不是检查空指针,而是检查两个变量.如果mynull永远不会在代码中发生变化并且编译器优化常量将0折叠到if语句中,这可能会有效,但这不能保证,并且编译器必须根据C标准生成至少一条诊断消息(警告或错误).
请注意,C语言中的空指针是什么.它与底层架构无关.如果底层架构的空指针值定义为地址0xDEADBEEF,那么由编译器来排除这个混乱局面.
因此,即使在这个有趣的架构上,以下方法仍然是检查空指针的有效方法:
if (!pointer)
if (pointer == NULL)
if (pointer == 0)
Run Code Online (Sandbox Code Playgroud)
以下是检查空指针的INVALID方法:
#define MYNULL (void *) 0xDEADBEEF
if (pointer == MYNULL)
if (pointer == 0xDEADBEEF)
Run Code Online (Sandbox Code Playgroud)
因为这些被编译器视为正常比较.
'\0'
被定义为空字符 - 这是一个所有位都设置为零的字符.这与指针无关.但是,您可能会看到类似于此代码的内容:
if (!*string_pointer)
Run Code Online (Sandbox Code Playgroud)
检查字符串指针是否指向空字符
if (*string_pointer)
Run Code Online (Sandbox Code Playgroud)
检查字符串指针是否指向非空字符
不要将这些与空指针混淆.仅仅因为位表示是相同的,并且这允许一些方便的交叉情况,它们实际上不是同一个东西.
另外,'\0'
(像所有字符文字一样)是一个整数常量,在这种情况下值为零.所以'\0'
完全等同于一个朴实的0
整数常量 - 唯一的区别在于它传达给人类读者的意图("我将它用作空字符.").
有关更多信息,请参阅comp.lang.c常见问题解答的问题5.3.有关C标准,请参阅此pdf.查看6.3.2.3指针,第3节.
小智 33
似乎很多人误解了NULL,'\ 0'和0之间的区别.所以,要解释,并试图避免重复前面说过的事情:
类型为int的类型为0的常量表达式,或者此类型的表达式,强制转换为类型void*是一个空指针常量,如果转换为指针,则变为空指针.标准保证比较不等于任何指向任何对象或函数的指针.
NULL是一个宏,定义为空指针常量.
'\ 0'是用于表示空字符的结构,用于终止字符串.
一个空字符是有它的所有位设置为0字节.
Nas*_*sko 13
所有三个都在不同的上下文中定义了零的含义.
当你看到记忆时,这三个总是不同的:
NULL - 0x00000000 or 0x00000000'00000000 (32 vs 64 bit)
NUL - 0x00 or 0x0000 (ascii vs 2byte unicode)
'0' - 0x20
Run Code Online (Sandbox Code Playgroud)
我希望这能澄清它.
如果NULL和0等效为空指针常量,我应该使用哪个?在C FAQ列表中也解决了这个问题:
C程序员必须理解它
NULL
并且0
在指针上下文中是可互换的,并且uncast0
是完全可以接受的.任何使用NULL(相对于0
)都应该被认为是一个温和的提示,指示涉及指针; 程序员不应该依赖它(无论是为了他们自己的理解还是编译器)来区分指针0
和整数0
.它只在指针上下文中
NULL
并且0
是等价的.NULL
当需要另一种0
时,即使它可能有效,也不应该使用它,因为这样做会发送错误的风格信息.(此外,ANSI允许的定义NULL
是((void *)0)
,不会在非指针上下文在所有的工作.)特别是,不使用NULL
该ASCII空字符(时NUL
)是期望的.提供您自己的定义
#define NUL '\0'
Run Code Online (Sandbox Code Playgroud)
如果你必须.
NULL,'\ 0'和0之间有什么区别
"null character(NUL)"最容易排除. '\0'
是一个字符文字.在C中,它实现为int
,因此,它与0相同,即0 INT_TYPE_SIZE
.在C++中,字符文字实现为char
1字节.这通常与NULL
或不同0
.
接下来,NULL
是一个指针值,指定变量不指向任何地址空间.抛开它通常被实现为零的事实,它必须能够表达体系结构的完整地址空间.因此,在32位架构上,NULL(可能)是4字节,64位架构是8字节.这取决于C的实施.
最后,文字0
是类型int
,大小INT_TYPE_SIZE
.默认值INT_TYPE_SIZE
可能因架构而异.
Apple写道:
Mac OS X使用的64位数据模型称为"LP64".这是Sun和SGI以及64位Linux的其他64位UNIX系统使用的通用数据模型.LP64数据模型定义了基本类型,如下所示:
- 整数是32位
- 多头是64位
- 多头也是64位
- 指针是64位
维基百科64位:
Microsoft的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 ?
Run Code Online (Sandbox Code Playgroud)
编辑:在字符文字上添加更多内容.
#include <stdio.h>
int main(void) {
printf("%d", sizeof('\0'));
return 0;
}
Run Code Online (Sandbox Code Playgroud)
上面的代码在gcc上返回4,在g ++上返回1.
一篇对我开始学习 C 很有帮助的好文章(摘自 Linden 的《专家 C 编程》)
一个“l”nul 和两个“l”null
记住这个小韵律可以回忆起指针和 ASCII 零的正确术语:
The one "l" NUL ends an ASCII string,
The two "l" NULL points to no thing.
Apologies to Ogden Nash, but the three "l" nulll means check your spelling.
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
277843 次 |
最近记录: |