为什么printf字面打印(null)以及究竟发生了什么?

时间:2015-07-21 19:54:50

标签: c printf format-specifiers

在C编程练习中,我做了类似的事情(只是简化):

printf( "%s", 0);

输出

(null)

这里发生了什么?我假设printf将零解释为char *,那么NULL? 我怎么能用

之类的东西复制这个结果
char string[] = NULL; //compiler-error
printf( "%s", string);

4 个答案:

答案 0 :(得分:6)

首先,你的

printf("%s", 0);

导致未定义的行为(UB)。 %s中的printf需要char *指针作为参数。您正在传递0 int。仅这一点就已经破坏了你的代码,就像

一样
printf("%s", 42); 

会。对于那个特定的UB,0的事实没有任何区别。

其次,如果你真的想尝试将null-ponter传递给%s格式说明符,你必须做类似的事情

printf("%s", (char *) 0);

当然,这也会导致未定义的行为,因为%s需要指向有效字符串的指针作为参数,而(char *) 0不是有效的字符串指针。但有些实现更喜欢优雅地处理这种情况,只需打印(null)

在你的特殊情况下,你很幸运:printf("%s", 0)"工作"与printf("%s", (char *) 0)相同,您的实施通过输出(null)来保存当天。

答案 1 :(得分:2)

正如其他人所说,将空指针传递给printf %s并不能保证做任何事情。在其他条件相同的情况下,由于printf尝试取消引用空指针,因此我们会预期会发生分段违规或其他不合理的崩溃。然而,为了方便起见,printf的许多(大多数?)实现在其中的某个深处,等同于

case 's':
    char *p = va_arg(argp, char *);
    if(p == NULL) p = "(null)";
    fputs(p, stdout);

答案 2 :(得分:1)

您也可以使用以下内容执行此操作:

char *string = NULL;

printf("%s", string);

printf()的许多实现会在向(null)传递NULL指针时打印%s或类似内容。但他们不必这样做(标准不要求这样做。)

答案 3 :(得分:1)

在您的示例中,将0传递给printf会导致未定义的行为,因为您所使用的格式说明符表示它会打印一个字符串,但您给它一个int。要复制,您可以这样做:

char *string = NULL;
printf("%s", string);