为什么 printf 从字面上打印 (null) 以及究竟发生了什么?
Why does printf literally print (null) and what exactly happens?
在 C 编程练习中,我正在做这样的事情(只是简化):
printf( "%s", 0);
输出为
(null)
这里发生了什么?我假设 printf
将零解释为 char *
,所以 NULL
?
我怎样才能通过类似
的方式复制这个结果
char string[] = NULL; //compiler-error
printf( "%s", string);
?
您也可以使用类似的方式执行此操作:
char *string = NULL;
printf("%s", string);
许多 printf()
的实现在将 NULL
指针传递给 %s
时将打印 (null)
或类似内容。但他们不必这样做(标准没有要求)。
在您的示例中,将 0 传递给 printf
会导致未定义的行为,因为您的格式说明符说它打印一个字符串,但您给它一个 int。要复制,您可以这样做:
char *string = NULL;
printf("%s", string);
首先,你的
printf("%s", 0);
导致未定义的行为 (UB)。 printf
中的 %s
需要一个 char *
指针作为参数。您正在传递 0
,这是一个 int
。仅此一项就已经破坏了您的代码,就像
printf("%s", 42);
会。对于那个特定的 UB,0
是 零 的事实没有任何区别。
其次,如果您真的想尝试将空指针传递给 %s
格式说明符,则必须执行类似
的操作
printf("%s", (char *) 0);
当然,这也会导致未定义的行为,因为 %s
需要指向有效字符串的指针作为参数,而 (char *) 0
不是有效的字符串指针。但是有些实现更喜欢优雅地处理这种情况,只打印 (null)
.
在您的特定情况下,您很幸运:printf("%s", 0)
"worked" 与 printf("%s", (char *) 0)
相同,您的实施通过输出 (null)
挽救了这一天。
正如其他人所指出的,将空指针传递给 printf %s
并不能保证做任何事情。在其他一切都相同的情况下,我们预计会出现分段违规或其他不正常的崩溃,因为 printf
试图取消引用空指针。然而,为方便起见,printf
的许多(大多数?)实现在其深处的某处具有
的等价物
case 's':
char *p = va_arg(argp, char *);
if(p == NULL) p = "(null)";
fputs(p, stdout);
在 C 编程练习中,我正在做这样的事情(只是简化):
printf( "%s", 0);
输出为
(null)
这里发生了什么?我假设 printf
将零解释为 char *
,所以 NULL
?
我怎样才能通过类似
char string[] = NULL; //compiler-error
printf( "%s", string);
?
您也可以使用类似的方式执行此操作:
char *string = NULL;
printf("%s", string);
许多 printf()
的实现在将 NULL
指针传递给 %s
时将打印 (null)
或类似内容。但他们不必这样做(标准没有要求)。
在您的示例中,将 0 传递给 printf
会导致未定义的行为,因为您的格式说明符说它打印一个字符串,但您给它一个 int。要复制,您可以这样做:
char *string = NULL;
printf("%s", string);
首先,你的
printf("%s", 0);
导致未定义的行为 (UB)。 printf
中的 %s
需要一个 char *
指针作为参数。您正在传递 0
,这是一个 int
。仅此一项就已经破坏了您的代码,就像
printf("%s", 42);
会。对于那个特定的 UB,0
是 零 的事实没有任何区别。
其次,如果您真的想尝试将空指针传递给 %s
格式说明符,则必须执行类似
printf("%s", (char *) 0);
当然,这也会导致未定义的行为,因为 %s
需要指向有效字符串的指针作为参数,而 (char *) 0
不是有效的字符串指针。但是有些实现更喜欢优雅地处理这种情况,只打印 (null)
.
在您的特定情况下,您很幸运:printf("%s", 0)
"worked" 与 printf("%s", (char *) 0)
相同,您的实施通过输出 (null)
挽救了这一天。
正如其他人所指出的,将空指针传递给 printf %s
并不能保证做任何事情。在其他一切都相同的情况下,我们预计会出现分段违规或其他不正常的崩溃,因为 printf
试图取消引用空指针。然而,为方便起见,printf
的许多(大多数?)实现在其深处的某处具有
case 's':
char *p = va_arg(argp, char *);
if(p == NULL) p = "(null)";
fputs(p, stdout);