C 为什么printf处理浮点参数的方式与处理双参数的方式完全相同?

C 为什么printf处理浮点参数的方式与处理双参数的方式完全相同?,c,floating-point,printf,C,Floating Point,Printf,直到最近,我还以为: float f = 1234.5; double d = 12345678.9; printf("Output = %u %u\n",sizeof(f),sizeof(d)); // Output = 4 8 printf("Output = %.1f %.1f\n",f,d); // Output = 1234.5 12345678.9 printf(“%f”,x)将尝试从堆栈中读取4字节浮点值 printf(“%lf”,x)将尝试从堆栈中读

直到最近,我还以为:

float  f = 1234.5;
double d = 12345678.9;
printf("Output = %u %u\n",sizeof(f),sizeof(d)); // Output = 4 8
printf("Output = %.1f %.1f\n",f,d);             // Output = 1234.5 12345678.9
  • printf(“%f”,x)
    将尝试从堆栈中读取4字节浮点值

  • printf(“%lf”,x)
    将尝试从堆栈中读取8字节浮点值

但是,以下代码似乎产生了正确的输出:

float  f = 1234.5;
double d = 12345678.9;
printf("Output = %u %u\n",sizeof(f),sizeof(d)); // Output = 4 8
printf("Output = %.1f %.1f\n",f,d);             // Output = 1234.5 12345678.9
我相信它证明了
printf(“%f”,x)
从堆栈中读取8字节的浮点值

这是因为两个值都正确打印,但12345678.9太大,无法装入4字节变量

现在我的问题是:当使用4字节的
float
变量调用
printf
时,编译器如何知道在将其推入堆栈并调用
printf
之前应该将其强制转换为8字节的
double

调用采用浮点参数的函数时,这是标准的一部分吗

谢谢

编译器如何知道在将其推入堆栈并调用printf之前应该将其强制转换为8字节的双精度值

它不必知道什么时候做——它总是知道;这是我们的一部分

调用采用浮点参数的函数时,这是标准的一部分吗

不,只是可变的

编译器如何知道在将其推入堆栈并调用printf之前应该将其强制转换为8字节的双精度值

它不必知道什么时候做——它总是知道;这是我们的一部分

调用采用浮点参数的函数时,这是标准的一部分吗


不,只是变量。

这是一个变量问题。哦。。。因此,只有当将
float
变量传递给一个函数时才会出现这种情况,该函数采用了可变数量的参数(通过
vararg
),例如
printf
?是的,可以传递char和float,但必须以int和double的形式检索它们。好的,我在过去认识到了
char
short
,但我认为每个函数调用都会发生“四舍五入到4的倍数”(因此假设
char/short/int/float
都将作为4字节参数传递,而不管
vararg
问题如何)。。。感谢您提供的信息:)既然您知道
printf
参数必须与格式字符串匹配,请使用
..%zu…”、sizeof(…)
..%u…”、(unsigned int)sizeof(…)
。使用
%u
打印
sizeof
的结果可能会失败,因为
size\u t
不必是
unsigned int
。这是一个很重要的问题。哦。。。因此,只有当将
float
变量传递给一个函数时才会出现这种情况,该函数采用了可变数量的参数(通过
vararg
),例如
printf
?是的,可以传递char和float,但必须以int和double的形式检索它们。好的,我在过去认识到了
char
short
,但我认为每个函数调用都会发生“四舍五入到4的倍数”(因此假设
char/short/int/float
都将作为4字节参数传递,而不管
vararg
问题如何)。。。感谢您提供的信息:)既然您知道
printf
参数必须与格式字符串匹配,请使用
..%zu…”、sizeof(…)
..%u…”、(unsigned int)sizeof(…)
。使用
%u
打印
sizeof
的结果可能会失败,因为
size\u t
不必是
unsigned int