核心格式说明符
double 类型对应的 printf 格式说明符是 %f。

(图片来源网络,侵删)
这个说明符告诉 printf 函数:“接下来要处理的是一个双精度浮点数,请将其转换为十进制浮点数形式进行输出。”
基本用法
最简单的用法就是直接使用 %f。
#include <stdio.h>
int main() {
double my_double = 3.141592653589793;
// 基本输出
printf("The value of my_double is: %f\n", my_double);
return 0;
}
输出结果:
The value of my_double is: 3.141593
注意: 你会发现输出的小数位数是固定的(通常是6位),这是因为 %f 默认会显示6位小数。

(图片来源网络,侵删)
控制输出精度
很多时候,我们希望控制输出的小数位数,这时,可以在 和 f 之间加上一个 和一个数字,表示“保留N位小数”。
格式:%.[N]f
N是你想要保留的小数位数。
示例代码:
#include <stdio.h>
int main() {
double pi = 3.141592653589793;
double price = 99.9876;
// 保留2位小数
printf("Pi with 2 decimal places: %.2f\n", pi);
// 保留4位小数
printf("Pi with 4 decimal places: %.4f\n", pi);
// 保留0位小数(即只输出整数部分)
printf("Price with 0 decimal places: %.0f\n", price);
return 0;
}
输出结果:
Pi with 2 decimal places: 3.14
Pi with 4 decimal places: 3.1416
Price with 0 decimal places: 100 // 注意:这里会进行四舍五入
控制输出宽度和对齐
你可以指定一个最小输出宽度,并控制文本是左对齐还是右对齐。
右对齐(默认)
在 和 f 之间加上一个数字,表示该字段的最小宽度,如果实际内容宽度不足,会用空格填充在左侧。
格式:%[width]f
示例代码:
#include <stdio.h>
int main() {
double num1 = 12.3;
double num2 = 123.456;
// 指定最小宽度为10
printf("Number 1 with width 10: |%10f|\n", num1);
printf("Number 2 with width 10: |%10f|\n", num2);
// 结合精度控制
printf("Number 1 with width 10 and 2 decimals: |%10.2f|\n", num1);
return 0;
}
输出结果:
Number 1 with width 10: | 12.300000| // 数字前有7个空格
Number 2 with width 10: |123.456000| // 数字前有1个空格
Number 1 with width 10 and 2 decimals: | 12.30| // 数字前有6个空格
左对齐
在宽度数字前面加上一个 号,表示左对齐。
格式:%[-width]f
示例代码:
#include <stdio.h>
int main() {
double num = 12.3;
// 左对齐,最小宽度为10
printf("Number left-aligned with width 10: |%-10f|\n", num);
// 左对齐,结合精度控制
printf("Number left-aligned with width 10 and 2 decimals: |%-10.2f|\n", num);
return 0;
}
输出结果:
Number left-aligned with width 10: |12.300000 | // 数字后有7个空格
Number left-aligned with width 10 and 2 decimals: |12.30 | // 数字后有6个空格
你可以将宽度、精度和对齐方式组合起来,形成一个完整的格式说明符。
格式:%[flags][width][.precision]f
flags: 控制对齐等,如 (左对齐), (总是显示正负号),` (正数前加空格),0` (用0填充)。width: 最小输出宽度。precision: 小数点后的位数。
综合示例:
#include <stdio.h>
int main() {
double value = -123.456789;
// 1. 右对齐,宽度10,保留2位小数
printf("Right-aligned: |%10.2f|\n", value);
// 2. 左对齐,宽度10,保留2位小数
printf("Left-aligned: |%-10.2f|\n", value);
// 3. 总是显示正负号,宽度10,保留2位小数
printf("Show sign: |%+10.2f|\n", value);
// 4. 用0填充,宽度10,保留2位小数
printf("Zero-padded: |%010.2f|\n", value);
// 5. 组合使用:左对齐,宽度15,保留4位小数,总显示正负号
printf("Complex: |%-+15.4f|\n", value);
return 0;
}
输出结果:
Right-aligned: | -123.46|
Left-aligned: |-123.46 |
Show sign: | -123.46|
Zero-padded: |-0000123.46|
Complex: |-123.4568 |
double 和 float 的 printf 区别
在 printf 中,%f 和 %lf 的行为有些特殊,需要特别注意。
-
float类型:- 当你使用
float变量时,推荐使用%f。 - 在 C 语言中,
float在传递给可变参数函数(如printf)时,会自动被提升为double类型。printf实际上接收到的总是一个double。%f和%lf对于float变量来说效果是一样的。
- 当你使用
-
double类型:- 当你使用
double变量时,必须使用%f。 - 如果你错误地使用
%lf,在大多数现代编译器(如 GCC, Clang)上可能不会报错,并且能正确输出,但这并非标准规定,是一种常见的“扩展”或“遗留”行为,为了代码的清晰和可移植性,应该始终为double使用%f。
- 当你使用
-
scanf中的区别:- 这个区别在
scanf(输入函数)中是非常重要的。 scanf中,读取float变量必须用%f。scanf中,读取double变量必须用%lf,如果你用%f来读取double,会导致读取错误。
- 这个区别在
总结表格:
| 变量类型 | printf (输出) |
scanf (输入) |
|---|---|---|
float |
%f |
%f |
double |
%f |
%lf |
重要提示:浮点数精度问题
由于计算机采用二进制存储浮点数,很多十进制小数无法被精确表示,因此存在精度误差,这会影响输出。
#include <stdio.h>
int main() {
double a = 0.1;
double b = 0.2;
double c = a + b;
// 你期望的输出是 0.3,但实际可能不是
printf("0.1 + 0.2 = %.17f\n", c); // 输出更多位以查看误差
return 0;
}
可能的输出结果:
1 + 0.2 = 0.30000000000000004
这个误差是浮点数本身的特性,不是 printf 的问题,在进行需要高精度的金融计算时,应使用专门的库(如 GMP)或定点数表示法。
