为了澄清一点,我已经写了两个小测试程序。
#include <stdio.h>
int main(int argc, char *argv[])
{
char *p = "ab";
p++;
p++;
if (*p)
printf("p is not NULL \n");
else
printf("ps is NULL \n");
return 0;
}
上面的程序将char指针p
初始化为字符串文字ab
。我将指针递增两次,然后if循环检查p
是否指向非NULL字符。这样可以正常工作并提供以下输出。
ps is NULL
#include <stdio.h>
int main(int argc, char *argv[])
{
char *p = '\0';
if (*p)
printf("p is not NULL \n");
else
printf("ps is NULL \n");
return 0;
}
上面的程序将char指针p
初始化为NULL字符\0
。如果我编译并运行程序,我会得到分段错误。有人解释一下吗?
两种情况的唯一区别是NULL字符位于0
位置和2
位置。否则程序看起来与我相同。
答案 0 :(得分:7)
理解null 指针(NULL
)和null *字符('\0'
)之间的区别非常重要。
char *p = "ab";
p++;
p++;
这正确地将指针p
设置为指向字符串"ab"
末尾的空字符。
char *p = '\0';
这会将p
设置为null 指针。使用'\0'
作为空指针常量是不好的样式,但是合法的(任何具有零值的常量整数表达式都是有效的空指针常量)。以上相当于清晰度:
char *p = NULL;
任何取消引用p
的尝试都有未定义的行为,可能会导致程序崩溃。
两种情况的唯一区别是
NULL
字符位于第0位和第2位。
如果你想在0号位置使用空字符(不是NULL
字符),你可以写:
char *p = "\0";
或几乎等同于:
char *p = "";
空字符串只包含终止'\0'
空字符。
答案 1 :(得分:3)
您正在使用char*
值初始化int
。如果打开警告,编译器应该警告您。尝试:
char *p = "\0";
带双引号。
请注意,NUL(代码为0的字符)和NULL
(不指向任何东西的指针值)是完全不同的东西。
答案 2 :(得分:3)
两种情况的唯一区别是NULL字符位于0位置和位置2&#34;
这完全是假的。这两个程序实际上非常不同。
第一个程序使用类型为p
的数组初始化char [3]
。数组衰减到指针类型,这使得p
指向存储在内存中某处的字符串"ab"
。该字符串以位置\0
的{{1}}值结束,这正是您所观察到的。
第二个程序使用字符常量2
初始化p
。该常量的类型为\0
,值为int
。此初始化使用空指针值初始化0
。这相当于只做
p
结果char *p = NULL;
点无处可寻。检查p
会导致未定义的行为。
如果您希望第二个程序与第一个程序类似,则必须按
进行*p
或只是
char *p = "\0";
请注意双引号。这将使char *p = "";
指向内存中的p
值。但
\0
单引号的是一个完全不同的故事,如上所述。
答案 3 :(得分:1)
在C中,'\0'
是一个整数表达式,因此您有char *p = 0;
。因此,p
是一个NULL指针。
请参阅How do I get a null pointer in my programs? :
根据语言定义,在指针上下文中使用值“0”的“整数常量表达式”在编译时转换为空指针。也就是说,在一方是指针类型的变量或表达式的初始化,赋值或比较中,编译器可以告诉另一方的常量0请求空指针,并生成正确类型的空指针值。因此,以下片段是完全合法的:
char *p = 0; if(p != 0)