flo*_*jdt 2 c string null sizeof
我目前正在学习 C,我编写了这个程序来检查 '\0' 字符是否确实位于字符串末尾,如“K 和 R”中指出的那样。
但我得到了最奇怪的结果。
如果我评论“int lista[] = {0, 1, 2, 3, 4};” 程序中的语句(这是一个与该程序的其他语句无关的语句,它是我要做的另一个测试的一部分)。程序的输出结果与预期一致,检测到字符串结尾有一个“\0”字符。但是,如果我不注释该语句,则程序输出会在字符串末尾检测到两个“\0”字符。为什么会出现这种情况?
这是未注释语句的程序:
#include <stdio.h>
int main(void)
{
int lista[] = {0, 1, 2, 3, 4};
char string[] = "linhas";
for (int i = 0; i <= sizeof(string); i++)
{
if (string[i] != '\0')
{
printf("%c\n", string[i]);
}
else
{
printf("this dawmn null char\n");
}
}
}
Run Code Online (Sandbox Code Playgroud)
这输出:
l
i
n
h
a
s
this dawmn null char
this dawmn null char
Run Code Online (Sandbox Code Playgroud)
这是注释掉该行的程序:
#include <stdio.h>
int main(void)
{
/*int lista[] = {0, 1, 2, 3, 4};*/
char string[] = "linhas";
for (int i = 0; i <= sizeof(string); i++)
{
if (string[i] != '\0')
{
printf("%c\n", string[i]);
}
else
{
printf("this dawmn null char\n");
}
}
}
Run Code Online (Sandbox Code Playgroud)
它输出:
l
i
n
h
a
s
this dawmn null char
Run Code Online (Sandbox Code Playgroud)
你的循环
for (int i = 0; i <= sizeof(string); i++)
Run Code Online (Sandbox Code Playgroud)
是非常轻微的错误。它应该是
for (int i = 0; i < sizeof(string); i++)
Run Code Online (Sandbox Code Playgroud)
通过使用<=,您会在循环中进行太多次,并且会访问string数组外部的内存。看起来,在lista数组就位后,您错误访问的额外字节(在数组之外string)恰好是 0,因此您会得到“this dawmn null char”消息的额外第二个打印输出。
但是,当您注释掉该lista数组时,您错误访问的额外字节一定不是 0,因此它会被打印为本身。它可能是一个不可见的控制字符,这就是为什么你看不到任何东西。我建议将您的代码更改为
if (string[i] != '\0')
printf("string contains %d\n", string[i]);
else printf("this damn null char\n");
Run Code Online (Sandbox Code Playgroud)
为了更清楚地看到这一点。
这里重要的教训是,如果您有一个应该运行 N 次的循环,则有两种方法可以编写它。在 C 中,绝大多数时候,你想把它写成
for(i = 0; i < N; i++)
Run Code Online (Sandbox Code Playgroud)
这是一个“从 0 开始”的循环,从 0 运行到 N-1,总共 N 趟。有时,您需要一个基于 1 的循环:
for(i = 1; i <= N; i++)
Run Code Online (Sandbox Code Playgroud)
从 1 运行到 N,总共 N 次行程。但如果你写
for(i = 0; i <= N; i++) /* usually WRONG */
Run Code Online (Sandbox Code Playgroud)
您的循环从 0 运行到 N,总共 N+1 趟。