在 '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=]';
如上所述,使用单引号是完全不同的情况。
为了澄清一点,我编写了下面给出的两个小测试程序。
#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=]';
如上所述,使用单引号是完全不同的情况。