我无法理解以下两种情况下的输出。 编译器:Windows上的Borland C ++ 5.02 案例1:
#include <stdio.h>
int main()
{
char str[] = "HELLO";
printf("%abc %2s", str, str);
return 0;
}
output:%abc %2s
案例2:
#include <stdio.h>
int main()
{
char str[] = "HELLO";
printf("abc %2s", str, str); //% sign removed
return 0;
}
output:abc 1310540
请让我理解输出。如果它听起来很幼稚,请告诉我。我在C中很天真。
答案 0 :(得分:3)
这是我的猜测:
printf("%abc %2s", str, str);
您的古代编译器会在%a
格式字符串的引入之前提前发布。因此,运行时意识到它遇到了一个它无法识别的格式字符串,并放弃了尝试格式化。在任何情况下,您都无法将字符串传递给%a
并期望任何有意义的内容。因此,即使您的编译器理解'%a',行为也将是未定义的。试图理解UB几乎没有什么可以获得的。修复你的代码。
printf("abc %2s", str, str);
应输出
abc HELLO
甚至在您的古老编译器上也是如此。如果没有,那就是编译器运行时的错误。
我个人准备打赌您的编译器会为该程序生成该输出。我宁愿想象你的问题被错误地转录了。问题中的输出与代码不匹配,反之亦然。
这是由你的pastebin确认的:
#include<stdio.h>
int main()
{
char str[] = "HELLO";
printf("abc %d", str, str);//different from code in question
return 0;
}
Output: abc -1083086374
所以,不仅讨论UB有点无意义,当你运行的版本与问题中的代码不同时讨论程序更加毫无意义。将来,我建议您使用复制/粘贴将代码转换为Stack Overflow问题,然后进行双重和三重检查,确认输出是您声称的。
结论:现在是2013年。没有理由使用BCC v5.02。现在是时候向前迈进了。
答案 1 :(得分:0)
第一种是未定义的行为,因为您尝试将字符串打印为十六进制浮点。
第二个例子是有效的。它打印一个至少包含两个字符的字符串。忽略第二个参数str
。
答案 2 :(得分:0)
我不得不说你只需要阅读full POSIX documentation for printf
(你也可以从Linux控制台输入man 3p printf
)或者使用编译器/ C标准库实现的文档。
基本上,在%
字符之后遇到的字符以非常特定的方式解释。 %
后面的字符属于&#34;标记&#34;,&#34;长度修饰符&#34;和&#34;转换指定&#34; - 除转换说明符外,其中每个都是可选的。你的第二个例子应该给你一个警告,因为你有比你有转换说明符更多的值,它甚至看起来有一个bug,因为你不能使用数字标志(&#34; 2&#34;)和字符串转换说明符它吐出废话(可能是十进制的指针)。