-1

在以下两种情况下,我无法理解输出。编译器:Windows 上的 Borland C++ 5.02 案例 1:

#include <stdio.h>

int main()
{
    char str[] = "HELLO";
    printf("%abc %2s", str, str);
    return 0;
}
output:%abc %2s

案例二:

#include <stdio.h>

int main()
{
    char str[] = "HELLO";
    printf("abc %2s", str, str);  //% sign removed
    return 0;
}
output:abc 1310540

请让我理解输出。如果这听起来很幼稚,请原谅。我在 C 语言中有点天真。

4

3 回答 3

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。是时候及时向前迈进了。

于 2013-04-25T19:23:32.623 回答
0

第一个是未定义的行为,因为您尝试将要打印的字符串作为十六进制浮点数打印。

第二个例子是有效的。它打印一个至少包含两个字符的字符串。第二个参数str被忽略。

于 2013-04-25T19:09:48.637 回答
0

我不得不说您只需要阅读完整的 POSIX 文档printf(您也可以man 3p printf从 Linux 控制台键入)或带有编译器/C 标准库实现的文档。

基本上,在字符之后遇到的%字符以非常特定的方式进行解释。a 后面的字符%属于“标志”、“长度修饰符”和“转换指定”类别——除了转换说明符之外,每个都是可选的。您的第二个示例应该给您一个警告,因为您的值比转换说明符多,而且它甚至似乎有一个错误,因为您不能将数字标志(“2”)与字符串转换说明符一起使用并且它吐出废话(也许你的十进制指针)。

于 2013-04-25T19:12:30.707 回答