有更多的格式说明符或顺序可以与C printf语句中的参数不同吗?

huangapple go评论68阅读模式
英文:

Can there be more format specifiers or order can be different than arguments in a C printf statement?

问题

#include <stdio.h>

int main()
{
    int a = 9;
    float b = 1.23;
    double c = 6.2396734679;

    printf("%d %f %e", b, a);

    return 0;
}
输出是如何的 -> 9 1.230000 1.230000e+00 ??

参数顺序不正确 + 格式说明符是否可以比参数少?
英文:
#include <stdio.h>

int main()
{
int a =9;
float b = 1.23;
double c = 6.2396734679;

printf("%d %f %e",b,a);

return 0;
}

How is the output -> 9 1.230000 1.230000e+00 ??

The order of arguments is not correct + Can there be less arguments than format specifiers?

答案1

得分: 3

根据C11标准:

  • 如果格式说明符的数量超过提供的参数数量,行为是未定义的。
  • 如果提供了多余的参数,而格式字符串已经用尽,这些参数将被简单地忽略,不会涉及未定义的行为。
  • 顺序不能不同。第一个格式说明符必须与提供的第一个参数匹配,第二个格式说明符应与提供的第二个参数匹配,依此类推。如果任何参数与相应的转换规范不匹配,则行为是未定义的。
英文:

From the C11 standard:

> If there are insufficient arguments for the format, the behavior is
> undefined. If the format is exhausted while arguments remain, the
> excess arguments are evaluated (as always) but are otherwise ignored.
>
>...
>
> If any argument is not the correct type for the corresponding
> conversion specification, the behavior is undefined.

  • It is undefined behaviour if the number of format specifiers exceed the number of arguments provided.
  • If excess arguments are provided, and the format string is exhausted, the arguments are simply ignored, and there's no undefined behaviour involved.
  • The order shall not be different. The first format specifier must match the first argument provided, the second format specifier should match the second argument provided, and so on. If any argument is not the correct type for the corresponding conversion specification, the behavior is undefined.

答案2

得分: 2

> 在C printf语句中,格式说明符是否可以更多或顺序可以与参数不同?

是的,你可以这样做,而C标准没有定义在这样做时程序的行为,因此这是一个不好的主意,你不应该指望它能起作用。

在许多C实现中,前几个整数参数会通过通用处理器寄存器传递,前几个浮点参数会通过浮点寄存器传递。因此,被调用的例程将在通用寄存器中查找其整数参数(例如编号为'r8'、'r9'和'r10'的数字),并将在浮点寄存器中查找其浮点参数(例如'f4'、'f5'和'f6')。因此,如果交换整数和浮点参数,例程仍然会在通用寄存器中查找并找到整数参数,在浮点寄存器中查找并找到浮点参数。例如,'foo(1, 2, 3., 4.)'和'foo(1, 3., 2, 4.)'都会将整数值1和2放入用于参数的前两个通用处理器寄存器中,并将浮点值3和4放入用于参数的前两个浮点寄存器中。

你应该了解这种行为,因为它对于调试和理解计算机如何工作很有用,但你不应依赖它。当编译器启用优化时,高级转换可能会破坏这种行为。

一些C实现确实具有用于按不同顺序列出格式字符串中的参数的功能,可以使用转换说明中的附加字符(即告诉printf要做什么的包含'%'的字符串)来实现这一点。

英文:

> Can there be more format specifiers or order can be different than arguments in a C printf statement?

Yes, you can do this, and the C standard does not define the behavior of the program when you do, so it is a bad idea and you should not expect it to work.

In many C implementations, the first few integer arguments are passed in the general processor registers, and the first few floating-point arguments are passed in floating-point registers. So a called routine will look for its integer arguments in the general registers (say numbers r8, r9, and r10) and will look for its floating-point arguments in the floating-point registers (say f4, f5, and f6). Because of this, if you swap integer and floating-point arguments, the routine will still look for and find integer arguments in the general registers and floating-point arguments in the floating-point registers. For example, both foo(1, 2, 3., 4.) and foo(1, 3., 2, 4.) will put the integer values 1 and 2 in the first two general processor registers used for arguments and the floating-point values 3 and 4 in the first two floating-point registers used for arguments.

You should know about this behavior because it is useful for debugging purposes and for understanding how computers work, but you should not rely on it. When optimization is enabled in the compiler, advanced transformations may break this behavior.

Some C implementations do have features for listing the arguments in a format string in a different order than they appear in the function call, using additional characters in each conversion specification (the string with % that tells printf what to do besides echoing literal characters).

huangapple
  • 本文由 发表于 2023年3月20日 23:21:31
  • 转载请务必保留本文链接:https://go.coder-hub.com/75792147.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定