C语言之printf()函数

一、printf()的简介

基于C11标准

注意:编译器:TDM-GCC 4.9.2 64-bit Rlease;long int 到底是 32bits 还是 64bits 跟生成的程序是 32bits 还是 64bits 一一对应,如果使用 g++ 编译程序的话,可通过-m32或-m64选项分别生成 32bits 和 64bits 的程序。因本人测试代码编译生成的是 32bits 的程序,所以 long int 也就是 32btis。

printf() 是C语言标准库函数,定义于头文件 <stdio.h>

功能:按format指向的格式字符串所规定的格式,将输出表列args的值输出到标准输出设备上。即将指定数据输出到屏幕(命令提示符、显示器、控制台)上。可称之为:格式化输出函数。

1.printf()的声明

int printf(const char* format, args, ...)  

2.printf()之格式控制串、输出参数表、返回值

① printf()函数根据format(格式控制串)给出的格式打印输出到stdout(标准输出)和其它参数中。

格式控制串:指数据输入的格式

        格式控制串:格式字符+普通字符

        普通字符:将原样不动地复制到标准输出

        格式字符:转换说明符、标志、宽度、精度。

        转换说明符和百分号[%]一起使用,来说明内存中的数据输出的格式。由%开始,以转换转换说明符结束。

        format:可以是一个字符串,或是字符数组的其实地址。

输出参数表:待输出的数据,可以是常量、变量或其他更复杂的表达式,也可以没有输出项。

        当有多个输出项时,各输出项用逗号隔开。

        输出项必须与格式字符在类型和数量上完全对应。

④ 返回值

        输出字符的个数,若出错,返回负数。

二、format 转换说明组成

format 转换说明组成:

%[flags][width][.precision][length]specifier
 %[标志][最小宽度][.精度][类型长度]说明符 。注意:这代表一个格式控制符。

1😲说明符(specifier) 

        说明符(specifier)用于规定输出数据的类型,参照表:

2😀标志(flags)

标志(flags)用于规定输出样式,含义如下:

3😲最小宽度(width)

最小宽度(width)用于控制显示字段的宽度,取值和含义如下:

4😲精度(.precision)

5😊类型长度(length)

类型长度(length)用于控制待输出数据的数据类型长度,取值和含义如下:

6😮转义序列

转义序列在字符串中会被自动转换为相应的特殊字符。printf() 使用的常见转义字符如下

三、printf()实战

1.输出格式中的普通字符

        当printf()参数只有"格式控制串","格式控制串"中没有格式字符而只有普通字符时,函数完成的功能是将双引号中的字符串原样输出(显示在屏幕上)。

#include<stdio.h>
int main()
{
	printf("hello C! - 你好 C");
	return 0;
}

运行结果:

hello C! - 你好 C

2.输出格式中的转换字符串

        转换说明符规定了对应输出项的输出类型,即将输出的数据转换为指定的格式输出。该项不能省略。格式为:

        %转换说明符

2.1对有符号整数操作

#include<stdio.h>
int main()
{
	short int si = 1230;
	int in = 1231;
	long int li = 1232; 
	long long int lli = 1233;
	printf("对应类型字节位数: %d | %d | %d | %d\n", sizeof(short int),\
			 sizeof(int), sizeof(long int), sizeof(lli));
	printf("si = %hd | in = %d | li = %ld | lli = %lld", si, in, li, lli);
	return 0;
}

运行结果:

对应类型字节位数: 2 | 4 | 4 | 8
si = 1230 | in = 1231 | li = 1232 | lli = 1233

2.2对无符号整数操作

#include<stdio.h>
int main()
{
	unsigned short int usi = 1230;
	unsigned int uin = 1231;
	unsigned long int uli = 1232; 
	unsigned long long int ulli = 1233;
	printf("对应类型的字节位数: %d | %d | %d | %d\n", sizeof(usi),\
			 sizeof(uin), sizeof(uli), sizeof(ulli));
	printf("si = %hu | in = %u | li = %lu | lli = %llu", usi, uin, uli, ulli);
	return 0;
}

运行结果:

对应类型的字节位数: 2 | 4 | 4 | 8
si = 1230 | in = 1231 | li = 1232 | lli = 1233

2.3对浮点数操作

#include<stdio.h>
int main()
{
	float flo = 13.14;
	double dou = 52.0;
	printf("对应类型字节位数: %d | %d\n", sizeof(flo), sizeof(dou));
	printf("flo = %f | dou = %lf", flo, dou);
	return 0;
}

运行结果:

对应类型字节位数: 4 | 8
flo = 13.140000 | dou = 52.000000

注:浮点数无符号类型同整数类型相似

2.4对字符和字符串操作

#include<stdio.h>
int main()
{
	char ch = 'H';
	char* str = "Hello C!";
	printf("对应类型的字节位数: %d | %d\n", sizeof(ch), sizeof(str));
	printf("ch = '%c' | str = \"%s\"\n", ch, str);
	printf("%hhd\n", 'A');		// 输出有符号 char
	printf("%hhu\n", 'A' + 128);// 输出无符号 char
	return 0;
}

运行结果:

对应类型的字节位数: 1 | 8
ch = 'H' | str = "Hello C!"
65
193

2.5按八进制、十六进制输出

#include<stdio.h>
int main()
{
	int in = 1024;
	printf("%o | %x | %X", in, in, in, in);
	return 0;
}

运行结果:

2000 | 400 | 400

2.6按科学计数法输出

#include<stdio.h>
int main()
{
	double dou1 = 123456;
	double dou2 = -0.123456789;
	printf("%le | %lE | %le | %lE\n", dou1, dou1, dou2, dou2);
	printf("%lg | %lG | %lg | %lG", dou1, dou1, dou2, dou2);
	return 0;
}

结果:

1.234560e+005 | 1.234560E+005 | -1.234568e-001 | -1.234568E-001
123456 | 123456 | -0.123457 | -0.123457

2.7 %的输出、控制字符串的隐化

#include<stdio.h>
int main()
{
	int in = 1314;
	char *str = "%%:id(in) = %p";
	printf(str, &in);
	return 0;
}

运行结果:

%:id(in) = 000000000062FE14

3.输出格式中的宽度修饰符

3.1 带常量宽度的输出

#include<stdio.h>
int main()
{
	int in = 1314520;
	
	printf("%5d | %10d", in, in);
	return 0;
}

运行结果:

1314520 |    1314520

3.2带变量宽度的输出

#include<stdio.h>
int main()
{
	int in = 1314520;	
	printf("%*d | %*d | %*0d", 3, in, 10, in, 1, in);
	return 0;
}

运行结果:

1314520 |    1314520 |    1314520

4.输出格式中标志、宽度修饰符

4.1指定左右对齐、显示正负号输出

#include<stdio.h>
int main()
{
	int in = 1314520;	
	printf("%+10d | %-10d", in, in);
	return 0;
}

运行结果:

  +1314520 | 1314520

4.2指定空余字符用0填充

#include<stdio.h>
int main()
{
	int in = 1314520;
	char* str = "1314520";
	printf("%.4d | %.10d\n", in, in);	// %.10d 等价于 %010d 
	printf("%0+10d | %0-10d  | %010s | %0-10s", in, in, str, str);
	return 0;
}

运行结果:

1314520 | 0001314520
+001314520 | 1314520     | 0001314520 | 1314520

4.3输出格式前缀修饰符#

#include<stdio.h>
int main()
{
	int in = 1024;
	printf("%#o | %#X", in, in);	// 带前缀八进制、十六进制输出 
	return 0;
}

运行结果:

02000 | 0X400

5.输出格式中精度修饰符

5.1按指定常量位数输出小数

#include<stdio.h>
int main()
{
	double dou = 3.1415926;
	printf("%.4lf | %.10lf", dou, dou);		// 自动四舍五入 
	return 0;
}

运行结果:

3.1416 | 3.1415926000

注:对浮点数进行截断时,会有四舍五入。

5.2按指定变量位数输出小数

#include<stdio.h>
int main()
{
	double dou = 3.1415926;
	printf("%*.4lf | %*.*lf", 15, dou, 20, 10, dou);		// 自动四舍五入 
	//变动宽度15格.常量保留小数点后4位 | 变动宽度20位.变量保留点后10位 
	return 0;
}

运行结果:

         3.1416 |         3.1415926000

5.3 输出指定位数字符串(可以自动截断)

#include<stdio.h>
int main()
{
	char str[] = "Hello C Programming!";
	printf("%.10s", str); 
	return 0;
}

运行结果:

Hello C Pr

6.输出格式中类型长度修饰符

类型长度指明待输出数据的长度。因为相同类型可以有不同的长度,可参考下表

😲😀用于解释带和不带长度说明符的相应参数的类型(下表)

注: 黄色背景行标识的类型长度说明符和相应的数据类型是C99引入的。

参考:http://www.cplusplus.com/reference/cstdio/printf/?kw=printf

6.1 整型的不同长度类型

#include<stdio.h>
#include<limits.h>
int main()
{
	short si = (1 << 15) -1;
	int in = (1 << 31) -1 ;
	long li = (1 << 31) -1;
	long long lli = (1 << 63) -1;
	printf("%hd | %d | %ld %lld\n", si, in, li, lli);
	printf("%hd | %d | %ld | %lld\n", SHRT_MIN, INT_MIN, LONG_MIN,LLONG_MIN);
	printf("%+hd | %+d | %+ld | %+lld", SHRT_MAX, INT_MAX, LONG_MAX,LLONG_MAX);
	return 0;
}

运行结果:

32767 | 2147483647 | 2147483647 -1
-32768 | -2147483648 | -2147483648 | -9223372036854775808
+32767 | +2147483647 | +2147483647 | +9223372036854775807

6.2 浮点型的不同长度类型

#include<stdio.h>
#include<limits.h>
int main()
{
	float fl = 1 << 31, flo = (1 << 30)-1+(1 << 30);
	double dou = 1 << 31, doub = (1 << 30)-1+(1 << 30);
	printf("%f | %lf\n", fl, dou);			// 注:fl 达不到预期值 dou 
	printf("%f | %lf\n", flo, doub);
//	printf("%f | %lf\n", FLT_MIN, DBL_MIN);	// <limits.h>未预配置 FLT_MIN范围,但用此编译器预测了一下 
//	printf("%+f | %+lf", FLT_MAX, DBL_MAX);
	return 0;
}

运行结果:

-2147483648.000000 | -2147483648.000000
2147483648.000000 | 2147483647.000000

6.3 字符和字符串的宽度

#include<stdio.h>
int main()
{
	char str[] = "Hello C Programming!";
	printf("%.8s | %8s", str, str);	// %.8s与 %8s含义不同,%.8s可以截断指定位数字符 
	return 0;
}

运行结果:

Hello C  | Hello C Programming!

7.输出格式中有转义字符修饰

7.1 \n的使用

#include<stdio.h>
int main()
{
	char str[] = "Hello\n C Programming!";	// \n :跳到下一行 
	printf(str);
	return 0;
}

运行结果:

Hello
 C Programming!

7.2 \\和\t的使用

#include<stdio.h>
int main()
{
	char str[] = "Hello\\n \t Programming!";	// \\n : 解释为 \ 加上 n 
	printf(str);
	return 0;
}

输出结果:

Hello\n C        Programming!

四、printf()缓冲

在 printf 的实现中,在调用 write 之前先写入 IO 缓冲区,这是一个用户空间的缓冲。系统调用是软中断,频繁调用,需要频繁陷入内核态,这样的效率不是很高,而 printf 实际是向用户空间的 IO 缓冲写,在满足条件的情况下才会调用 write 系统调用,减少 IO 次数,提高效率。

可参考参考文献:printf函数打印(二)—— 缓冲区篇(文件读写再探究)_printf flush-CSDN博客

五、小节

       本文详细讲解了printf()的格式控制串的含义及其应用。首次在CSDN上发表文章难免会出现错误,敬请指正,不胜感激;文章内容渲染不足,样式单一,还望海涵。耗时漫长,如意完成printf()基础内容,但内容详实丰富。

本文参考文献:

printf(格式化输出函数)_百度百科 (baidu.com)

C语言printf() 详解之终极无惑_printf头文件-CSDN博客

在线工具:

C 在线工具 | 菜鸟工具 (runoob.com)icon-default.png?t=N7T8https://c.runoob.com/compile/11/C库函数:文章开篇

  • 18
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值