简体   繁体   English

`printf()` 如何区分浮点参数和整数类型参数?

[英]How does `printf()` distinguish between floating point arguments and integer type arguments?

If I have如果我有

printf("%f\n", 3);

I get我得到

3.000000

And if I have:如果我有:

printf("%f\n", 3.0);

I get the same answer.我得到同样的答案。

But here's the thing, 3 and 3.0 should be completely different, bit wise.但事情是这样的,3 和 3.0 应该完全不同,有点明智。

3.0 should be something like 01000000010000000000000000000000 (but double precision because of implicit conversion in vararg functions) 3.0 应该类似于01000000010000000000000000000000 (但由于可变参数函数中的隐式转换而导致双精度)
3 should be something like 00000000000000000000000000000011 3 应该类似于00000000000000000000000000000011

3 must somehow be converted to a float before being displayed. 3 在显示之前必须以某种方式转换为浮点数。

So my question is, how is this done?所以我的问题是,这是如何完成的? Does the compiler cheat somehow?编译器会作弊吗? How would I implement this in my own variable args function?我将如何在我自己的变量 args 函数中实现它?

If your source code contained printf("%f\\n", 3);如果你的源代码包含printf("%f\\n", 3); and the resulting output was “3”, then what most likely happened was something like:结果输出是“3”,那么最有可能发生的事情是这样的:

  • There is a floating point 3 somewhere else in your program, such as for an assignment statement like x = 3.;在你的程序的其他地方有一个浮点 3,例如像x = 3.;这样的赋值语句x = 3.; or another printf call such as printf("%f\\n", 3.0);或另一个printf调用,例如printf("%f\\n", 3.0); . .
  • In order to work with that 3, the compiler loaded it into a floating-point register.为了使用那 3,编译器将它加载到一个浮点寄存器中。 It might have done this for code prior to your printf or as preparation for code that is after your printf .它可能已经为您的printf之前的代码或为您的printf之后的代码做准备。
  • When printf("%f\\n", 3);printf("%f\\n", 3); was evaluated, that floating-point 3 was in the register where a double argument is supposed to be when printf was called with a %f conversion specifier.经评估,浮点 3 位于寄存器中,当使用%f转换说明符调用printf时, double参数应该在该寄存器中。
  • So, since the register used to pass an argument for %f happened to have a floating-point 3 in it, the printf used that value and produced a result of “3”.因此,由于用于为%f传递参数的寄存器中碰巧有一个浮点数 3,所以printf使用该值并产生结果“3”。

In other words, your program happened to “work” largely by happenstance, not by design.换句话说,你的程序碰巧“工作”主要是偶然的,而不是设计的。 You did in fact call printf incorrectly, and it only produced “3” because unrelated factors happened to work out.事实上,你确实错误地调用了printf ,它只产生了“3”,因为不相关的因素发生了。 If the value in that floating-point register had been 5 or −3.25, then printf would have printed that value instead.如果该浮点寄存器中的值是 5 或 -3.25,则 printf 将改为打印该值。

The printf routine does not have a way of determining which types of values you passed it. printf例程无法确定您传递给它的值类型。 (Good compilers do check the types at compile-time, if the format string is a literal [rather than something computed at run-time]. But that is done by the compiler looking at the source code for the call, not by the printf routine itself.) (好的编译器会在编译时检查类型,如果格式字符串是文字[而不是在运行时计算的东西]。但这是由编译器查看调用的源代码完成的,而不是由printf常规本身。)

How does printf() distinguish between floating point arguments and integer type arguments? printf()如何区分浮点参数和整数类型参数?

printf() relies on the calling code to pass objects of the expected type per its format . printf()依赖于调用代码根据其格式传递预期类型的对象。


printf() analyzes the format string , which in this case is "%f\\n" . printf()分析格式字符串,在本例中为"%f\\n"

The "%f" steers code to expect that the next parameter is a double . "%f"引导代码期望下一个参数是double

If a float is passed, it is converted to a double as part of the usual conversion of arguments to the ... part of a function.如果传递了一个float ,它会被转换为double float数,作为参数到函数的...部分的通常转换的一部分。

With a float/double passed by the calling code, printf() will properly get that data as a double and print it.通过调用代码传递float/doubleprintf()将正确地将该数据作为double float/double获取并打印出来。 If the calling code passed some other type, the result is undefined behavior (UB) .如果调用代码传递了其他类型,则结果是未定义行为(UB) This UB is well explain by @Eric Postpischil . @Eric Postpischil很好地解释了这个 UB。

how is this done?这是怎么做的? Does the compiler cheat somehow?编译器会作弊吗?

How would I implement this in my own variable args function?我将如何在我自己的变量 args 函数中实现它?

The unexpected undefined behavior seen by OP is not certainly reproducible with user code. OP 看到的意外未定义行为肯定不能用用户代码重现

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM