在C语言中,各种零值之间似乎存在差异——NULL、NUL和0。

我知道ASCII字符“0”的值为48或0x30。

NULL指针通常定义为:

#define NULL 0

Or

#define NULL (void *)0

此外,还有NUL字符“\0”,它的值似乎也是0。

是否存在这三个值不能相等的情况?

在64位系统上也是这样吗?


当前回答

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。

其他回答

(void*) 0是NULL, '\0'表示字符串的结束。

如果NULL和0是等价的空指针常数,我应该使用哪个?在C常见问题解答列表中也解决了这个问题:

C programmers must understand that NULL and 0 are interchangeable in pointer contexts, and that an uncast 0 is perfectly acceptable. Any usage of NULL (as opposed to 0) should be considered a gentle reminder that a pointer is involved; programmers should not depend on it (either for their own understanding or the compiler's) for distinguishing pointer 0's from integer 0's. It is only in pointer contexts that NULL and 0 are equivalent. NULL should not be used when another kind of 0 is required, even though it might work, because doing so sends the wrong stylistic message. (Furthermore, ANSI allows the definition of NULL to be ((void *)0), which will not work at all in non-pointer contexts.) In particular, do not use NULL when the ASCII null character (NUL) is desired. Provide your own definition

#define NUL '\0'

如果你一定要的话。

在ASCII表中,值为0x00的字节是称为NUL或NULL的特殊字符。在C语言中,因为你不应该在源代码中嵌入控制字符,所以这是用C字符串表示的,带有一个转义0,即\0。

但是一个真NULL不是一个值。它是一个值的缺失。对于指针来说,这意味着指针没有可指向的对象。在数据库中,它意味着字段中没有值(这与字段为空白、0或填充空格不同)。

给定的系统或数据库文件格式用来表示NULL的实际值不一定是0x00。

NULL不能保证为0——它的确切值取决于体系结构。大多数主流架构将其定义为(void*)0。

'\0'将总是等于0,因为这是字节0在字符字面值中编码的方式。

我不记得C编译器是否被要求使用ASCII——如果不是,'0'可能并不总是等于48。无论如何,除非您在非常晦涩的系统上工作,否则您不太可能遇到使用像EBCDIC这样的替代字符集的系统。

各种类型的大小在64位系统上有所不同,但整数值是相同的。


一些评论者表示怀疑NULL等于0,但不是0。下面是一个示例程序,以及在这样一个系统上的预期输出:

#include <stdio.h>

int main () {
    size_t ii;
    int *ptr = NULL;
    unsigned long *null_value = (unsigned long *)&ptr;
    if (NULL == 0) {
        printf ("NULL == 0\n"); }
    printf ("NULL = 0x");
    for (ii = 0; ii < sizeof (ptr); ii++) {
        printf ("%02X", null_value[ii]); }
    printf ("\n");
    return 0;
}

该程序可以输出:

NULL == 0
NULL = 0x00000001

“NUL”不是0,而是指ASCII的NUL字符。至少,我看到它是这样使用的。空指针通常定义为0,但这取决于您正在运行的环境,以及您正在使用的操作系统或语言的规范。

在ANSI C中,空指针被指定为整数值0。所以任何不符合标准的世界都是不符合ANSI C的。