其实,C语言没有提供专门的数据输入、输出语句,所有数据的输入输出都是通过调用标准库函数中的输入入、输出函数来实现。
一.printf()函数的一般形式为:
printf("格式控制串",输出列表);
- 格式控制串:
格式说明符(以”%”开始)、转义字符(以”\”开始)和普通字符。
- 输出列表:
常量、变量或表达式。
ps:
如果格式控制串中没有格式说明符,那么该输出语句里就不能有输出列表,也不需要表示分隔的逗号,这是printf()函数的最简单的形式。
二.格式说明符
在格式说明符中,可以利用修饰符控制输出项的对齐方式以及输出的宽度和精度。
1. %md输出时,可以指定输出数据的宽度,m表示输出的整型数据所占总宽度(即列数),其中:
- 当实际数据的位数不到m位时,数据左面将用空格补满。
- 若实际数据位数大于m,则以数据的实际位数为准进行输出。
- 若实际数据的位数不到m位时,在数据右面用空格补满,则格式符为:%-md。
- 输出时,当实际数据的位数不到m位时,数据左面用0补足,其格式说明符为:%0md。
实例1:
实际数据位数为1,不到2位,数据左面用空格补满。
实例2:
实际数据位数为3,超过2位,以实际位数3输出。
实例3:
实际数据位数为1,不到2位,数据右面用空格补满。
实例4:
实际数据位数为1,不到5位,数据左面用0补满。
实例5:
- 若要给输出的八进制数加前导0,给输出的十六进制数加前导0x,在 % 与格式字符o和x之间插入一个 #号,即%#o、%#x。
通过加#,就可以实现带前导的输出了。
2.%m.nf(m,n为正数),指定输出的数据共占m列,其中有n位小数,其中:
- 如果数值长度小于m,则左端补空格;
- 如果在小数点后取n位后,所规定的数据宽度m不够输出数据前面的整数部分(包括小数点),则整数部分按实际的位数进行输出。
- %f 以小数形式输出一个浮点数(含单双精度数),整数部分全部输出,并输出6位小数。
- 如果为%-m.nf则是向左对齐,右端补空格。
- 宽度,表示输出时所有的数字和小数点所占的位数,不够位数,左侧补空格。
- 精度(精确到小数点后多少位),四舍五入。
如果输出以下数据:
1314.520
则宽度为8,精度为3。
那这个宽度是指的原数据的宽度,还是输出后的宽度呢?
但当采用以下格式时:
原数据宽度为7个数字,一个小数点。我们要求输出时宽度为八,精度为一。
发现前面补了两个空格,说明所谓宽度是指输出时的宽度。
精度是怎么得到的,直接截断还是四舍五入呢?
如果是直接截断,那应该是 1314.2,可结果是 1314.3,说明才用的是四舍五入。
总得来说,当实际长度超过宽度时,以实际长度为准。当实际长度低于宽度时,补满空格。但精度确决定小数点后的位数,并采用四舍五入。
3.注意事项:
- 格式串中的格式说明符的个数必须和输出列表中的输出项个数相同,否则将引起错误。
- 格式说明符总是由一个%开始,以一个格式字符结束,中间可以有若干个修饰符,且格式字符要区分大小写,一般用小写字母。
- 如果想输出字符“%”时,则应该在“格式控制串”中用连续的两个%。
编译程序只是检查printf()函数的调用形式,不分析格式字符串,如果格式字符与输出项类型不匹配,不进行类型转换。
错误分类及现象:
(1)如果格式说明符的个数少于输出项的个数,多余的输出项不予输出。
(2)如果格式说明符的个数多于输出项的个数,则对于多余的格式将输出不确定值。
对大多数C编译系统,函数printf()输出项的计算顺序是从右至左,而输出顺序是从左至右。
以VS为例:
如果输出项是i++,则当即处理该输出项。如果是++i,则只执行++i运算并不将结果作为输出结果,并将输出项位置压入堆栈,只有当所有输出项从右向左处理完毕之后,再从堆栈弹出所有因延后操作而没有填入最终结果的输出项位置,将最终执行的结果i,作为相应的结果输出。
通俗来说,++i,就是在先加完,等结束后,再赋值,然后输出。而i++则是先赋值,然后直接输出,最后再自加。
对此例分析,虽然输出是从左向右的,但是计算确是从右向左的。
- 对倒数第一个位置,即对i++计算,先赋值,此时i是0,然后直接赋值为0。再加加,此时i是1。
- 对倒数第二个位置,即对++i计算,先加加,此时i是2,并不赋值。
- 对倒数第三个位置,即对i++计算,先赋值,此时i是2,然后直接赋值为2。再加加,此时i是3。
- 对倒数第四个位置,即对++i计算,先加加,此时i是4,此时计算结束,对倒数第二个位置和倒数第四个位置赋值,结果为4。
- 然后进行输出,输出是从左向右,则为4,2,4,0。