printf("%s", NULL) 和 printf("%s\n", NULL) 的区别?

printf("%s\n", (char*)NULL) 跟 printf("%s", (char*)NULL); fflush(stdout); 有什么区别? 为什么前者会导致Segmentation fault 后者打印(null)
关注者
48
被浏览
15847
更新:的确,汇编并不是有效的的方法,只能看到部分编译器的现象,要真正理解c的行为还是要啃标准。
~~~~~~~~~最骚的分割线~~~~~~~~~~
刚刚在知乎找到这个问题,然后发表了自己的结果,然后就在stackoverflow找到了答案,不得不说stackoverflow真是很厉害,至少每一个程序员都应该懂得利用这个网站(还有Google[顺便吐槽一下百度搜索出来都是什么鬼无聊东西,还是趁早退百度保平安])

首先,我们分别编译两个文件

#include <stdio.h>
int main(void){
    printf("%s", (char *)NULL);
}

#include <stdio.h>
int main(void){
    printf("%s\n", (char *)NULL);
}

通过附加-save-temps选项来查看汇编代码
这是"%s"的
这是"%s\n"的
可以发现,
"%s"这个是调用了printf函数进行处理,就像 @陈硕 所说的printf把这个当成了一种情况来处理,识别到这是一个NULL指针,
而"%s\n"这个则是直接调用了puts函数来进行输出,对于NULL指针并没有作判断处理,所以才会引发Segmentation fault。


而这个又正好解决了我的疑问,为什么再"%s\n"在任何位置加一点东西又不会引发Segmentation fault, 原因在于这次put又不足以解析这一段字符串,把他交给了printf来处理

以下附答案连接

What is the behavior of printing NULL with printf's %s specifier?

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




---原答案----

我也遇到这个问题
printf("%s1\n", (char *)NULL);
printf("1%s\n", (char *)NULL);
printf("%s\n1", (char *)NULL);
printf("%s", (char *)NULL);
printf("%s\n1", (char *)NULL);
printf("%s\t", (char *)NULL);
printf("%s\n", (char *)NULL);
这么多,就是最后一个会Segmentation fault
但是只要稍微改一下就不会出现,只有这个特定的格式才会出现,这是什么BUG