3.1 printf 函数
- printf 函数被设计用来显示格式串(format string)的内容,并且在该串中的指定位置插入可能的值。调用 printf 函数时必须提供格式串,格式串后面的参数是需要在显示时插入到该串中的值,显示的值可以是常量、变量或者更加复杂的表达式:
printf(格式串, 表达式1, 表达式2, ...);
- 调用 printf 函数一次可以打印的值的个数没有限制。
- 格式串包含普通字符和转换说明(conversion specification),其中转换说明以字符“%”开头。转换说明是用来表示打印过程中待填充的值的占位符。跟随在字符“%”后边的信息指定了把数值从内部形式(二进制)转换成打印形式(字符)的方法,这也就是“转换说明”这一术语的由来。格式串中的普通字符完全如在字符串中出现的那样显示出来,而转换说明则要用待显示的值来替换。
- C语言编译器不会检测格式串中转换说明的数量是否和输出项的数量相匹配。此外,C语言编译器也不检测转换说明是否适合要显示项的数据类型。
3.1.1 转换说明
- 转换说明给程序员提供了大量对输出格式的控制方法。另一方面,转换说明很可能很复杂且难以阅读。
- 转换说明可以包含格式化信息。转换说明可以用
%m.pX
格式或%-m.pX
格式,这里的 m 和 p 都是整数常量,而 X 是字母。m 和 p 都是可选的。如果省略 p,m 和 p 之间的小数点也要去掉。 - 最小字段宽度(minimum field width)m 指定了要显示的最少字符数量。如果要显示的数值所需的字符数少于 m,那么值在字段内是右对齐的。(换句话说,在值前面放置额外的空格。)如果要显示的值所需的字符数多于 m,那么字段宽度会自动扩展为所需的尺寸,而不会丢失数字。在 m 前放上一个负号会导致左对齐。
- 精度(precision)p 的含义很难描述,因为它依赖于转换说明符(conversion specifier)X 的选择。X 表明在显示数值前需要对其进行哪种转换。对数值来说最常用的转换说明符有以下几个:
- d —— 表示十进制形式的整数。p 指明了待显示的数字的最少个数(必要时在数前加上额外的零);如果省略 p,则默认它的值为 1。
- e —— 表示指数(科学记数法)形式的浮点数。p 指明了小数点后应该出现的数字的个数(默认值为 6)。如果 p 为 0,则不显示小数点。
- f —— 表示“定点十进制”形式的浮点数,没有指数。p 的含义与在说明符 e 中的一样。
- g —— 表示指数形式或者定点十进制形式的浮点数,形式的选择根据数的大小决定。p 说明可以显示的有效数字(没有小数点后的数字)的最大数量。与转换说明符 f 不同,g 的转换将不显示尾随的零。此外,如果要显示的数值没有小数点后的数字,g 就不会显示小数点。
- 编写程序时无法预知数的大小或者数值变化范围很大的情况下,说明符 g 对于数的显示是特别有用的。在用于显示大小适中的数时,说明符 g 采用定点十进制形式。但是,在显示非常大或非常小的数时,说明符 g 会转换成指数形式以便减少所需的字符数。
[程序] 用 printf 函数格式化数:tprintf.c
/* Prints int and float values in various formats */
#include <stdio.h>
int main(void)
{
int i;
float x;
i = 40;
x = 839.21f;
printf("|%d|%5d|%-5d|%5.3d|\n", i, i, i, i);
printf("|%10.3f|%10.3e|%-10g|\n", x, x, x);
return 0;
}
- 程序的输出如下:
|40| 40|40 | 040|
| 839.210| 8.392e+02|839.21 |
%d
—— 以十进制形式显示变量 i,且占用最少的空间。%5d
—— 以十进制形式显示变量 i,且至少占用 5 个字符的空间。因为变量 i 只占两个字符,所以添加了 3 个空格。%-5d
—— 以十进制形式显示变量 i,且至少占用 5 个字符的空间。因为表示变量 i 的值不需要用满 5 个字符,所以在后续位置上添加空格(更确切地说,变量 i 在长度为 5 的字段内是左对齐的)。%5.3d
—— 以十进制形式显示变量 i,且至少占用 5 个字符的空间并至少有 3 位数字。因为变量 i 只有 2 个字符长度,所以要添加一个额外的零来保证有 3 位数字。现在只有 3 个字符长度,为了保证占有 5 个字符,还要添加 2 个空格(变量 i 是右对齐的)。%10.3f
—— 以定点十进制形式显示变量 x,且总共用 10 个字符,其中小数点后保留 3 位数字。因为变量 x 只需要 7 个字符(即小数点前 3 位,小数点后 3 位,再加上小数点本身 1 位),所以在变量 x 前面有 3 个空格。%10.3e
—— 以指数形式显示变量 x,且总共用 10 个字符,其中小数点后保留 3 位数字。因为变量 x 总共需要 9 个字符(包括指数),所以在变量 x 前面有 1 个空格。%-10g
—— 既可以以定点十进制形式显示变量 x,也可以以指数形式显示变量 x,且总共用 10 个字符。在这种情况下,printf 函数选择用定点十进制形式显示变量 x。负号的出现强制进行左对齐,所以有 4 个空格跟在变量 x 后面。
3.1.2 转义序列
- 格式串中常用的代码
\n
被称为转义序列(escape sequence)。转义序列使字符串包含一些特殊字符而不会使编译器引发问题,这些字符包括非打印的(控制)字符和对编译器有特殊含义的字符(如“ " ”),下面这是一组示例:
- 警报(响铃)符:
\a
。 - 回退符:
\b
。 - 换行符:
\n
。 - 水平制表符:
\t
。
- 当这些转义序列出现在 printf 函数的格式串中时,它们表示在显示中执行的操作。在大多数机器上,输出
\a
会产生一声鸣响,输出\b
会使光标从当前位置回退一个位置,输出\n
会使光标跳到下一行的起始位置,输出\t
会把光标移动到下一个制表符的位置。 - 字符串可以包含任意数量的转义序列。
- 另一个常用的转义序列是
\"
,它表示字符“ " ”。因为字符“ " ”标记字符串的开始和结束,所以它不能出现在没有使用上述转义序列的字符串内。 - 不能在字符串中只放置单独一个字符“\”,编译器将认为它是一个转义序列的开始。为了显示单独一个字符“\”,需要在字符串中放置两个“\”字符。