[英]Why do we need to specify type in format specifiers in the C++ printf function?
[英]why do printf in C need to specify type of data
我想知道为什么我们需要指定像“%f”这样的数据类型来打印浮点的“x”变量。 “x”已经是一个浮点数,所以为什么我们需要再次告诉程序我们打印一个浮点变量。 这可能看起来像一个愚蠢的问题,但我很好奇其背后的原因。
float x = 5.0;
printf("%f",x);
为什么 printf... 需要指定数据类型(?)
int printf(const char * restrict format, ...);
是一个可变参数 function 。 printf()
不直接接收通过format
参数传递的其他信息或它们的类型的信息。
printf()
使用该format
来了解以下...
arguments 的计数、位置和类型。
格式参数有多种鲜为人知的替代方案。 例如
编译器在编译时就知道有关变量类型的信息,但它不会像其他一些语言那样为正在运行的程序保留任何这些信息。 在运行时,当调用 printf() 时,您必须提供在编译过程中丢失的类型信息。
他们是否可以编写编译器来使用编译时信息来编译对 printf() 的不同调用? 是的。 但这会使 printf() 与所有其他函数不同,并且以用户无法为自己编写的方式“神奇”。 现在完成的方式,您可以自己编写类似 printf() 的函数。
这是 function 的可变参数函数在 C 中的工作原理。 printf
的原型是
int printf( const char * restrict format, ... );
只有第一个参数format
是已知的固定类型。 任何额外的 arguments 没有固定的顺序或类型。 例如,如果你写
printf( "%d %s %f\n", 1, "2", 3.14159 );
编译器通过评估附加的 arguments 并将其结果推入堆栈或将它们写入特定寄存器来设置 function 调用。 但是,调用者无法将其他 arguments 的数量或类型传达给printf
。 arguments 本身没有任何内容来指示它们的类型或有多少。 printf
只是在堆栈上看到一堆字节(或一堆参数寄存器),但它并不神奇地知道如何从中挑选特定项目。
这就是为什么您需要格式字符串中的转换说明符来告诉printf
会发生什么。
在其他语言中,它通过generics 、 inheritance或多态性来解决
Generics 类似于<genericType T> void print(T)
(我没有任何示例)
As for inheritance, in Java, you have System.out.println(Object)
function that receives any type (everything inherits Object
)
而且每个Object
都有toString
方法告诉它要打印什么(如何表示)
最后,我们在 C++ 中看到的多态性
您可以在其中重载std::cout
的<<
运算符
像std::ostream& operator<<(std::ostream& os, const Date& dt)
在这种情况下,链接器/编译器选择哪个方法(具有相同的名称;标准是/是参数的类型)
C 没有(故意)任何这些东西
可能是因为它想保持“简单”(接近,但不太接近组装)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.