在 'C' 中检查 NULL 字符时的奇怪行为

Strange behaviour when checking for NULL character in 'C'

为了澄清一点,我编写了下面给出的两个小测试程序。

#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 character.This 工作正常并给出以下输出。

ps is NULL 

#include <stdio.h>


int main(int argc, char *argv[])
{
    char *p = '[=13=]';                                                                                                                                                                      

    if (*p)
        printf("p is not NULL \n");
    else
        printf("ps is NULL \n");

    return 0;
}

上面的程序将 char 指针 p 初始化为 NULL 字符 [=18=]。如果我编译 运行 程序,我得到分段 fault.Can 有人解释一下吗?

这两种情况的唯一区别是 NULL 字符位于位置 0 和位置 2。否则程序看起来与我相同。

您正在用 int 值初始化 char*。如果你打开警告,你的编译器应该警告你。尝试:

char *p = "[=10=]";

带双引号。

请注意,NUL(代码为 0 的字符)和 NULL(不指向任何内容的指针值)是完全不同的东西。

了解空 指针 (NULL) 和空 * 字符 ('[=16=]') 之间的区别很重要。

char *p = "ab";
p++;
p++;

这正确地将指针 p 设置为指向字符串末尾的空字符 "ab"

char *p = '[=11=]';

这会将 p 设置为空 指针 。使用 '[=16=]' 作为空指针常量是一种糟糕的风格,但却是合法的(任何值为零的常量整数表达式都是有效的空指针常量)。上面相当于更清晰:

char *p = NULL;

任何取消引用 p 的尝试都具有未定义的行为,并且可能会使您的程序崩溃。

The only difference in the two cases is the NULL character is at position 0 and position 2.

如果你想在0位置有一个空字符(不是NULL字符),你可以这样写:

char *p = "[=13=]";

或者,几乎等价地:

char *p = "";

空字符串仅包含终止 '[=16=]' 空字符。

在 C 中,'[=11=]' 是一个整数表达式,所以你有 char *p = 0;。因此,p 是一个 NULL 指针。

此外,请注意 NULL pointer versus the NUL 字符之间的区别。

How do I get a null pointer in my programs? :

According to the language definition, an ``integral constant expression with the value 0'' in a pointer context is converted into a null pointer at compile time. That is, in an initialization, assignment, or comparison when one side is a variable or expression of pointer type, the compiler can tell that a constant 0 on the other side requests a null pointer, and generate the correctly-typed null pointer value. Therefore, the following fragments are perfectly legal:

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

The only difference in the two cases is the NULL character is at position 0 and position 2"

那是完全错误的。这两个程序其实差别很大。

第一个程序用 char [3] 类型的数组初始化 p。数组衰减为指针类型,这使得 p 指向存储在内存中某处的字符串 "ab" 。该字符串在 2 位置以 [=18=] 值结尾,这正是您所观察到的。

第二个程序用字符常量 [=18=] 初始化 p。该常量具有类型 int 和值 0。此初始化使用空指针值初始化 p。这相当于只做

char *p = NULL;

结果p指向任何地方。检查 *p 会导致未定义的行为。

如果你想让你的第二个程序与第一个程序相似,你必须这样做

char *p = "[=11=]";

或者只是

char *p = "";

注意双引号。这将使 p 指向内存中的 [=18=] 值。但是

char *p = '[=13=]';

如上所述,使用单引号是完全不同的情况。