在' C'

时间:2015-06-04 22:15:12

标签: c pointers null

为了澄清一点,我已经写了两个小测试程序。

#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位置。否则程序看起来与我相同。

4 个答案:

答案 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指针。

另外,请注意NULL指针与NUL字符之间的区别。

请参阅How do I get a null pointer in my programs?

  

根据语言定义,在指针上下文中使用值“0”的“整数常量表达式”在编译时转换为空指针。也就是说,在一方是指针类型的变量或表达式的初始化,赋值或比较中,编译器可以告诉另一方的常量0请求空指针,并生成正确类型的空指针值。因此,以下片段是完全合法的:

char *p = 0;
if(p != 0)