Ste*_*epp 3 c printf type-conversion implicit-conversion conversion-specifier
使用 int 进行 float 隐式转换时,失败并显示 printf()
#include <stdio.h>
int main(int argc, char **argv) {
float s = 10.0;
printf("%f %f %f %f\n", s, 0, s, 0);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
用它编译时gcc -g scale.c -o scale会输出垃圾
./scale
10.000000 10.000000 10.000000 -5486124068793688683255936251187209270074392635932332070112001988456197381759672947165175699536362793613284725337872111744958183862744647903224103718245670299614498700710006264535590197791934024641512541262359795191593953928908168990292758500391456212260452596575509589842140073806143686060649302051520512.000000
Run Code Online (Sandbox Code Playgroud)
如果我显式地将整数转换为浮点数,或者使用 a 0.0(这是 a double),它会按设计工作。
#include <stdio.h>
int main(int argc, char **argv) {
float s = 10.0;
printf("%f %f %f %f\n", s, 0.0, s, 0.0);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
当用它编译时gcc -g scale.c -o scale确实输出预期的输出
./scale
10.000000 0.000000 10.000000 0.000000
Run Code Online (Sandbox Code Playgroud)
怎么了 ?
gcc (Debian 10.2.1-6) 10.2.1 20210110如果这很重要的话我正在使用。
转换说明符f需要一个 类型的对象double。通常sizeof( double )等于8whilesizeof( int )等于4。此外,整数和双精度数具有不同的内部表示形式。
使用不正确的转换说明符会导致未定义的行为。
来自 C 标准(7.21.6.1 fprintf 函数)
9 如果转换规范无效,则行为未定义。275)如果任何参数不是相应转换规范的正确类型,则行为未定义。
至于类型的对象float,由于默认参数提升,它们会转换为类型double。
来自 C 标准(6.5.2.2 函数调用)
6 如果表示被调用函数的表达式具有不包含原型的类型,则对每个参数执行整数提升,并且具有 float 类型的参数将提升为 double。这些称为默认参数促销。
所以这些电话printf
printf("%f %f %f %f\n", s, 0.0, s, 0.0);
Run Code Online (Sandbox Code Playgroud)
和
printf("%f %f %f %f\n", s, 0.0f, s, 0.0f);
Run Code Online (Sandbox Code Playgroud)
相对于结果是等价的。
请注意,某些输出双精度数的程序员l在转换规范中使用长度修饰符,例如%lf。然而,长度修饰符没有任何作用,应该被删除。