printf("%s\n",str);给出分段错误但是 printf("%s",str);不要,其中 "str" 是一个字符串指针

printf("%s\n",str); gives segmentation fault but printf("%s",str); don't, where "str" is a string pointer

当我尝试 运行 以下代码时:

#include <stdio.h>
void main()
{
    char *a[10] = {"hi", "hello", "how"};
    int i = 0, j = 0;
    a[0] = "hey";
    for (i = 0;i < 10; i++)
    printf("%s", a[i]);
}

它给我的输出是:

heyhellohow(null)(null)(null)(null)(null)(null)(null)

而当我在 printf 语句中插入 '\n' 时:

#include <stdio.h>
void main()
{
    char *a[10] = {"hi", "hello", "how"};
    int i = 0, j = 0;
    a[0] = "hey";
    for (i = 0;i < 10; i++)
        printf("%s\n", a[i]);
}

它给了我以下输出:

hey
hello
how  
Segmentation fault

我尝试在线阅读 material,我发现这是因为格式说明符并自动将 printf 转换为 putsputs 无法识别 "%s\n",但我仍然无法理解。谁能简单解释一下。

prinf() 中的 %s 格式说明符传递空指针是未定义的行为。在一种情况下,运行时试图表现得很好,并针对这种情况显示“(null)”。在另一种情况下,未定义的行为是崩溃。

造成这种差异的一个可能原因是编译器工具链有时会将 printf("%s\n", xxx) 转换为等效的 puts(xxx)(GCC 在很多情况下肯定会这样做)。我想 puts() 对你的空指针不太友好。

就我个人而言,我喜欢 "%s" 将空指针显示为“(null)” - 它在添加一些快速调试日志记录时更加方便。但是,如果你这样做,当程序崩溃时你就不能抱怨,所以你不应该依赖它做任何其他事情。

您正在声明一个包含 10 个 char 指针的数组。赋值 a[0] = "hey",导致指针 a[0] 指向存储在只读存储器中的字符串文字 "hey",而你丢失了字符串文字 "hi" 的踪迹。

段错误是由在循环中将空指针传递给函数 printf() 引起的,超出第三个 element.This 称为未定义行为。