c 语言 printf 函数是 stdio.h 头文件里面最常用的标准库函数,核心作用就是向控制台标准输出流打印文本和变量数据,依靠格式控制字符串搭配格式占位符,把整数浮点数字符字符串等不同类型数据转换成可读文本输出,函数原型是 int printf (const char format, ...),返回值是成功输出的字符总个数,如果输出出错会返回负数,很多初学者只关心打印效果,忽略返回值,也经常踩格式符和变量类型不匹配的坑,比如 long 类型误用 % d,double 误用 % f,这类错误会造成输出乱码数值异常,printf 底层属于可变参数函数,会按照格式串里面占位符顺序依次读取后面传入参数,格式串里面普通字符原样输出,遇到百分号开头的占位符就读取后面参数做格式化转换。之所以学习 c 语言第一个程序就会用到 printf,是因为它是调试输出最基础工具,程序运行之后查看变量值,打印提示信息都离不开它,相比单纯 putchar puts,printf 支持混合多种类型数据,还能控制小数位数对齐宽度,功能更全面。实际使用第一步引入 stdio.h 头文件,第二步编写格式控制字符串,按需插入对应格式占位符,第三步准备好要输出的变量,注意变量类型和占位符严格匹配,第四步调用 printf,格式串后面依次传入变量,第五步编译运行查看控制台输出效果,第六步调试的时候检查类型匹配问题,根据需求增加宽度补零小数位等修饰符,最后理解缓冲区机制,printf 默认是行缓冲,遇到换行符或者程序结束才刷新输出缓冲区,如果没有换行有时候会看不到打印内容。
一 函数原型与参数说明
int printf (const char format, ...)
format 格式控制字符串,由普通文本和百分号占位符组成
... 可变参数列表,数量必须和占位符数量保持一致
返回值 成功输出字符数量,出错返回负值
二 常用格式占位符清单
% d 输出有符号十进制 int 整数
% u 输出无符号十进制 unsigned int
% ld 输出 long 长整型
% lld 输出 long long
% c 输出单个字符
% s 输出字符串
% f 输出 float 或者 double 小数
% lf 一般用于 scanf 输入 double,printf 里面 double 仍然用 % f
% x 十六进制小写输出
% X 十六进制大写输出
% o 八进制输出
% p 输出指针地址
%% 输出百分号本身
三 格式修饰符进阶用法
宽度控制 比如 %5d 整数占至少 5 位,不够前面补空格
补零写法 %05d 不足位数前面补 0
小数精度 %.2f 保留两位小数
左对齐 %-5d 默认是右对齐,负号改成左对齐
长整型标记 % ld 无符号长整型 % lu
四 基础代码示例
include
int main()
{
int a = 10;
double b = 3.14159;
char c = 'A';
printf("整数 %d 小数 %.2f 字符 %c\n", a, b, c);
return 0;
}
五 printf 重点原理与踩坑点
1 可变参数匹配 占位符数量和后面参数数量不一致,属于未定义行为,可能打印随机垃圾数值
2 类型不匹配 这是最高频错误,long 类型不能写 % d,unsigned int 不能写 % d
3 缓冲区原理 标准输出默认行缓冲,有时候程序异常退出,缓冲区里面 printf 内容没有刷新,调试的时候误以为 printf 没有执行,可以使用 fflush (stdout) 手动刷新缓冲区
4 字符串越界 如果 % s 对应的指针是空指针,printf 会直接崩溃
5 转义字符 格式串里面 \n 换行 \t 制表符 \ 输出反斜杠 " 输出双引号,这些转义字符要区分普通文本
六 printf 和 puts putchar 对比表
| 对比项目 | c 语言 printf 函数 | puts | putchar |
|---|---|---|---|
| 输出能力 | 多类型混合格式化输出 | 仅输出字符串,自动追加换行 | 只输出单个字符 |
| 格式占位符 | 支持 | 不支持 | 不支持 |
| 速度 | 相对慢,解析格式串开销大 | 较快 | 最快 |
| 返回值 | 输出字符总数 | 成功返回非负值,失败 EOF | 输出字符编码 |
【常见问题】
问题 1 c 语言 printf 函数里面 double 类型要用 % lf 吗
回答 1 c 语言 printf 函数输出 double 的时候不需要写 % lf,直接使用 % f 即可,c 语言 printf 函数可变参数提升规则,double 会保持 double 类型,% lf 主要是 scanf 输入 double 使用,很多人混淆 scanf 和 c 语言 printf 函数格式符。
问题 2 c 语言 printf 函数打印内容有时候不显示是什么原因
回答 1 c 语言 printf 函数默认行缓冲,输出内容先放在缓冲区,没有遇到换行或者程序正常结束就不会送到控制台,c 语言 printf 函数异常崩溃的时候缓冲区数据丢失,可以调用 fflush (stdout) 强制刷新缓冲区解决。
问题 3 c 语言 printf 函数占位符数量和参数数量不一样会怎么样
回答 1 c 语言 printf 函数属于可变参数函数,如果 c 语言 printf 函数占位符数量大于后面传入参数,程序会读取栈上随机内存,输出垃圾数值,属于未定义行为,编译部分编译器会给出警告,正式代码必须保证 c 语言 printf 函数占位符和参数一一对应。
【免责申明】
本内容 c 语言 printf 函数讲解仅用于编程学习参考,不同编译器对可变参数类型不匹配的警告策略存在差异,类型错误属于未定义行为,正式项目开发请遵循 ANSI C 标准,严格匹配格式符与变量类型,因照搬示例代码造成输出异常程序崩溃,使用者自行承担相关责任。


