以下两种只是一个巧合,只不过地址值的数值为0而已。0本身只不过是一个可以显示的字符,与内存并没有直接关系。在0与ASCII表中关联NULL做了关联,这样使得输入转义字符'\0',也可以将一个变量赋值为NULL。而'\0'对应的ASCII码又是第0号,char类型本质上就是int,运算时也会自动转换为int类型,所以'\0'与数字0的值也恰好相等。
#define _CRT_SECURE_NO_WARNINGS
#include#includeint main()
{
char arr = '\0';
printf("%d\n", ((void *)0) == NULL);
printf("%d\n", 0 == NULL);//1
printf("%d\n", '\0' == NULL);//1
system("pause");
return 0;
}
请相信我,以上这一切,都是一个美丽的误会。
源码中NULL的定义:#define NULL ((void *)0)
(void *)0:表示将0强转为void *类型,使得0成为一个地址,即内存编号最开始的位置,一般保存的是系统引导程序,所以NULL是地址变量,但是不能被修改。
ASCII码中,将NULL对应为编号为0,转义字符为:'\n'。但不要以为NULL是数字0,其输出的只是它的地址编号,并不代表数值大小。
可以用作字符串的结束位置,表示一个字符串的结束。
字符串遇0结束是将字符串某个字符内容赋值为0或者NULL(NULL的地址值为0),而指针是将地址赋值为0或者NULL,所以注意字符串比较时要比较的是内容而不是地址。
对此,以测试字符串长度代码举例:字符应该用内容与0或者NULL作比较,而不是用地址作比较。
#define _CRT_SECURE_NO_WARNINGS
#include#includevoid array_init(char *p, int n)
{
fgets(p, n, stdin);
p[strlen(p) - 1] = 0;
fputs(p, stdout);
printf("\n");
}
void array_len(char *p, int n) {
int len = 0;
while (*p != NULL)//字符应该用*p而不是p
{
len++;
p++;
}
printf("%d\n", len);
}
int main(int argc, char *argv[])
{
char arr[100] = "";
//init
array_init(arr, sizeof(arr) / sizeof(arr[0]));
//len
array_len(arr, sizeof(arr) / sizeof(arr[0]));
system("pause");
return 0;
}