在C编程练习中,我做了类似的事情(只是简化):
printf( "%s", 0);
输出
(null)
这里发生了什么?我假设printf
将零解释为char *
,那么NULL
?
我怎么能用
char string[] = NULL; //compiler-error
printf( "%s", string);
答案 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);