1.3 printf与格式化输出 | Printf and Formatted Output

发布于 2025-09-14  522 次阅读


printf与格式化输出 | Printf and Formatted Output

一、回顾与引入

在前面的章节中,我们学习了:

  • printf("Hello, World!"); - 输出固定文字
  • 变量的声明、赋值和使用

但是,我们声明的变量如果不能显示出来,那就像是把宝贝藏在了看不见的盒子里。今天我们就来学习如何让程序告诉我们变量里装了什么

想象一下,如果我们有一个存储年龄的变量int age = 18;,我们希望程序能把age存储的值“带入”到输出里,例如:

我的年龄是: 18

而不是每次都要手动写成:

printf("我的年龄是: 18");
// 这样写,prinf在输出“固定”的文字
// 一旦想要修改输出的内容,每次都要修改代码。

二、什么是格式化输出?

格式化输出就是按照我们指定的格式,将变量的值带入到文字中进行显示。

仍然以上面的例子为例,如果我们有一个存储年龄的变量int age = 18;,我们希望程序像填空题一样,把age的值带入到如下的输出里:

我的年龄是: ____ // 像填空题一样带入到这里

那么,我们需要告诉printf()语句的有三件事

  1. 除了变量要填的空,文字部分是什么
  2. 空白处要填入哪个变量
  3. 这个变量是什么类型的数据、以什么样的格式填入(保留几位小数、是否左右对齐等等)

三、格式化输出的基本语法

我们下面通过一个简单例子来看看,printf()语句在格式化输出中的用法。

简单示例:

//Printf_Basic.c
#include <stdio.h>

int main() {
    int age = 18;
    printf("我的年龄是: %d岁。", age);
    return 0;
}

输出结果:

我的年龄是: 18岁。

回顾一下我们之前介绍printf()输出一段固定文本的写法,比较一下这个例子中printf()与之前有什么不同:

printf("我的年龄是:18岁。");       // 输出固定文本
printf("我的年龄是:%d岁。", age);  // 输出文本和变量

是的,从输出固定文本到“带入”变量,在这个例子里,我们只需要在双引号的文本中,将想要放入变量的位置用%d替代,在双引号外用引文逗号分隔开,并附带上需要带入的变量名即可。

printf()的这种用法里,英文逗号前面用双引号括起来的部分,是格式控制字符串(Format String),它规定了printf()输出内容的格式,即“以什么样的格式显示”,在这个例子里,也就是我的年龄是: ____岁。;英文逗号后面紧随的部分,是需要带入的变量列表,在这个例子里,也就是一个整型变量age

问题随之而来:%d是什么?

四、格式说明符 - 变量的"身份证"

%d是C语言中格式说明符的一种

还记得我们说在格式化输出中,要告诉printf()的三件事么?其中第三件事是:

  1. 这个变量是什么类型的数据、以什么样的格式填入(保留几位小数、是否左右对齐等等)

在C语言中,我们就是使用 格式说明符(Format Specifier) 来告诉printf()要输出什么类型的变量。

基本格式说明符表

数据类型 格式说明符 说明 示例
int %d 十进制整数 printf("%d", 42); 输出: 42
char %c 单个字符 printf("%c", 'A'); 输出: A
float %f 浮点数 printf("%f", 3.14); 输出: 3.140000
double %lf 双精度浮点数 printf("%lf", 3.14159); 输出: 3.141590

记忆小技巧:

  • %d - decimal(十进制)
  • %c - character(字符)
  • %f - float(浮点数)
  • %lf - long float(长浮点数,即double)

五、一行输出多个变量

我们可以在一个printf()语句中输出多个变量:

printf("格式说明符1 格式说明符2 格式说明符3", 变量1, 变量2, 变量3);

示例:

//Printf_Multiple.c
#include <stdio.h>

int main() {
    int age = 20;
    char grade = 'B';
    float height = 168.5;

    printf("学生信息: 年龄%d岁, 成绩%c, 身高%.1f厘米", age, grade, height);

    return 0;
}

输出结果:

学生信息: 年龄20岁, 成绩B, 身高168.5厘米

重要提醒: 格式说明符的数量和顺序必须与后面变量的数量和顺序完全对应

六、控制输出格式

1. 控制小数位数

使用%.n f可以控制浮点数显示的小数位数:

//Printf_Precision.c
#include <stdio.h>

int main() {
    float pi = 3.14159;

    printf("默认格式: %f", pi);      // 输出: 3.141590
    printf("保留2位小数: %.2f", pi); // 输出: 3.14
    printf("保留4位小数: %.4f", pi); // 输出: 3.1416
    printf("不保留小数: %.0f", pi);  // 输出: 3

    return 0;
}

2. 控制输出宽度

使用%nd可以控制整数的输出宽度:

//Printf_Width.c
#include <stdio.h>

int main() {
    int num1 = 42;
    int num2 = 1234;

    printf("默认宽度: %d", num1);     // 输出: 42
    printf("宽度为5: %5d", num1);    // 输出:    42 (前面有3个空格)
    printf("宽度为5: %5d", num2);    // 输出: 1234 (刚好4位)

    return 0;
}

七、特殊字符与转义字符

在格式化输出中,有的时候我们需要输出一些特殊字符或转义字符。
那么在什么时候呢?举个例子,例如我们想要在printf中输出一个英文双引号:

printf("这是一个英文双引号:"。");

这样的语句是错误的。为什么?因为本来在printf("...")的用法中,两个英文双引号想要把输出的英文双引号括起来,但上面的语句中,第一个和第二个双引号率先配对,留下了最后落单的双引号,自然也就不符合语法。

printf("这是一个英文双引号:"。");
//     ↑-----------------↑  ^

为了解决这个问题,我们在输入英文双引号的时候,用\"来代替",向编译器标明这个双引号是我们要输出的内容。这样带有\开头或%开头的一些字符成为特殊字符或转义字符

有一些特殊字符有特殊含义:

转义字符 含义 示例
\n 换行 printf("第一行\n第二行");
\t 制表符(Tab) printf("姓名\t年龄");
\\ 反斜杠本身 printf("路径: C:\\Users");
\" 双引号本身 printf("他说:\"你好\"");
%% 百分号本身 printf("完成度: 85%%");

示例:

//Printf_Escape.c
#include <stdio.h>

int main() {
    printf("=== 学生成绩单 ===\n");
    printf("姓名\t年龄\t成绩\n");
    printf("张三\t18\tA\n");
    printf("李四\t19\tB+\n");
    printf("\n完成度: 100%%\n");
    printf("老师说:\"大家都很棒!\"\n");

    return 0;
}

输出结果:

=== 学生成绩单 ===
姓名  年龄  成绩
张三  18  A
李四  19  B+

完成度: 100%
老师说:"大家都很棒!"

八、常见错误与注意事项

1. 格式说明符与变量类型不匹配

int age = 18;
printf("%f", age);  // ❌ 错误:用%f输出int类型
printf("%d", age);  // ✅ 正确:用%d输出int类型

2. 格式说明符数量与变量数量不匹配

int a = 10, b = 20;
printf("%d %d %d", a, b);     // ❌ 错误:3个%d但只有2个变量
printf("%d %d", a, b, 30);    // ❌ 错误:2个%d但有3个变量
printf("%d %d", a, b);        // ✅ 正确:2个%d对应2个变量

3. 忘记包含stdio.h头文件

// ❌ 错误:没有包含头文件
int main() {
    printf("Hello");  // 编译器不认识printf
    return 0;
}

// ✅ 正确:包含头文件
#include <stdio.h>
int main() {
    printf("Hello");
    return 0;
}

4. 变量未初始化

int age;  // 声明但未赋值
printf("年龄: %d\n", age);  // ❌ 错误:输出未知值

int age = 18;  // ✅ 正确:先赋值再使用
printf("年龄: %d\n", age);

九、综合示例:个人信息显示程序

让我们用一个完整的程序来练习所学内容,你能看懂每一条语句在执行什么样的功能么?:

//Personal_Info.c
#include <stdio.h>

int main() {
    // 声明并初始化变量
    char name_initial = 'Z';
    int age = 20;
    float height = 175.8;
    float weight = 65.5;
    char blood_type = 'O';

    // 输出个人信息
    printf("===================\n");
    printf("   个人信息卡片   \n");
    printf("===================\n");
    printf("姓名首字母: %c\n", name_initial);
    printf("年龄: %d岁\n", age);
    printf("身高: %.1f厘米\n", height);
    printf("体重: %.1f公斤\n", weight);
    printf("血型: %c型\n", blood_type);
    printf("===================\n");

    // 计算并显示BMI (BMI = 体重(kg) / 身高(m)²)
    float height_in_meters = height / 100.0;  // 转换为米
    float bmi = weight / (height_in_meters * height_in_meters);
    printf("BMI指数: %.2f\n", bmi);

    return 0;
}

输出结果:

===================
   个人信息卡片   
===================
姓名首字母: Z
年龄: 20岁
身高: 175.8厘米
体重: 65.5公斤
血型: O型
===================
BMI指数: 21.24

十、动手练习

请编写一个程序,完成以下任务:

  1. 声明变量存储一个矩形的长和宽(使用float类型)
  2. 给这些变量赋值
  3. 计算矩形的周长和面积
  4. 用格式化输出显示所有信息,要求:
    • 长度和宽度保留1位小数
    • 周长和面积保留2位小数
    • 输出格式美观
// 参考答案
#include <stdio.h>

int main() {
    // 1. 声明变量
    float length;  // 长度
    float width;   // 宽度

    // 2. 给变量赋值
    length = 100.0;
    width = 50.0;

    // 3. 计算周长和面积
    float perimeter = 2 * (length + width); // 周长 = 2 × (长 + 宽)
    float area = length * width;      // 面积 = 长 × 宽

    // 4. 格式化输出
    printf("=== 矩形信息 ===\n");
    // 在这里添加你的printf语句
    printf("矩形的长度是:%.1f,宽度是:%.1f\n", length, width);
    printf("矩形的周长是:%.2f,面积是:%.2f\n", perimeter, area);

    return 0;
}

下一章预告: 在掌握了变量的输出后,我们将学习如何让程序接收用户输入,使用scanf()函数让程序变得更加互动!


这里是 /* Huajidawang */ 的个人主页