C语言之printf函数用法

1.printf函数概述

在C语言中,printf函数作为标准库<stdio.h>的核心输出工具,通过灵活的格式化字符串机制,实现了对多种数据类型的高精度、可定制化输出。其基本语法为int printf(const char format, ...),其中format字符串包含普通文本与格式说明符,后续可变参数列表提供待输出的变量值。格式说明符以%开头,后接类型标识符(如d、f、c等),并可通过修饰符调整输出样式,这种设计使得开发者能够精确控制数据的显示格式,满足从简单调试到复杂报表生成的多样化需求。
  格式说明符的类型标识符决定了数据的解析方式:%d用于输出有符号十进制整数,支持int、short等类型;%u对应无符号整数;%f默认输出6位小数的浮点数,而%e和%g则分别以科学计数法或自动选择%f/%e的紧凑形式呈现浮点数;字符与字符串通过%c和%s输出,其中字符串会自动追加空字符终止符;指针地址则通过%p以十六进制形式显示,通常配合void
类型使用。此外,%x和%X分别输出小写和大写的十六进制整数,%o用于八进制表示,这些进制转换功能在底层编程和位操作中尤为实用。

格式修饰符进一步扩展了输出控制能力。宽度修饰符通过%[数字]指定最小输出宽度,若实际数据长度不足,默认右对齐并用空格填充,例如printf("%5d", 42)输出" 42";结合-标志可改为左对齐(如printf("%-5d", 42)输出"42 ")。精度修饰符.[数字]对浮点数控制小数位数(如%.2f输出两位小数),对字符串则限制最大输出字符数(如printf("%.3s", "hello")输出"hel")。数字类型还可通过0标志用零填充(如printf("%05d", 42)输出"00042"),而+标志强制显示正负号(如printf("%+d", -5)输出"-5"),空格标志则对正数保留前导空格(如printf("% d", 5)输出" 5"),这些修饰符的组合使用(如printf("%+010.3f", 12.345))可生成高度规范化的数值输出。

特殊类型处理方面,printf通过%n将已输出字符数写入指定整型变量,这一特性在动态格式化中偶有应用,但需谨慎使用以避免安全风险。转义字符如\n(换行)、\t(制表符)、\(反斜杠)等可嵌入格式字符串,实现文本排版控制。对于非ASCII字符集(如中文),需确保源文件编码与终端编码一致,否则可能输出乱码;宽字符版本wprintf则专为Unicode设计,需配合<wchar.h>使用。

性能与安全性方面,printf因解析格式字符串的动态特性,相比直接输出函数(如puts)存在轻微性能开销,但在现代硬件上通常可忽略。其安全性风险主要源于格式字符串漏洞------若格式字符串来自用户输入且未经验证,恶意输入可能导致程序崩溃或信息泄露(如printf(user_input)可能引发任意内存读取)。因此,安全编码规范要求格式字符串必须为常量或严格验证的变量,或使用更安全的替代函数(如snprintf限制输出长度)。

综上,printf凭借其丰富的格式化能力,成为C语言输出操作的核心工具,广泛应用于调试日志、数据展示、交互界面等场景。开发者通过熟练掌握类型标识符、修饰符及标志的组合使用,能够高效实现从简单数值输出到复杂报表生成的多样化需求,同时需注意编码规范与安全实践以规避潜在风险。

2.函数原型

printf是C语言的标准输出函数,一般用于向标准输出设备按规定格式输出信息。函数原型如下:

c 复制代码
#include <stdio.h>
int printf(const char *format, ...);

printf函数使用格式为:printf("<格式化字符串>",参量表);

printf()是C语言标准库函数,在stdio.h中定义。输出的字符串除了可以使用字母、数字、空格和一些数字符号以外,还可以使用一些转义字符表示特殊的含义。

字符串常量原样输出,在显示中起提示作用。输出表列中给出了各个输出项,要求格式控制字符串和各输出项在数量和类型上应该一一对应。其中格式控制字符串是以%开头的字符串,在%后面跟有各种格式控制符,以说明输出数据的类型、宽度、精度等。

3.printf输出字体颜色

在有些时候我们希望通过printf输出的内容以不同的颜色在终端展示,这样在调试过程看起来更加直观。

printf输出颜色时的控制命令:/033[A1;A2;A3m

  • /033[为固定开头;

  • m为固定结尾;

  • A1表示属性;

  • A2表示字体颜色;

  • A3表示背景颜色;

  • A1参数

  • A2参数

  • A3参数

  • 示例

c 复制代码
#include <stdio.h>
int main()
{
	printf("\033[1;;41m%s\033[0m\n", "Hello World!");//字体加粗,背景为红色
	//加下划线,字体颜色为黑色,背景为白色
	printf("\033[4;30;47m%s\033[0m\n", "Hello World!");	
	printf("\033[5m%s\033[0m\n", "Hello World!");//字体闪烁
	printf("\033[;34m%s\033[0m\n", "Hello World!");//设置字体为绿色
	printf("\033[;;42m%s\033[0m\n", "Hello World!");//设置设置背景为绿色
}
  • 其它属性信息
  • \033[nA 光标上移n行
  • \03[nB 光标下移n行
  • \033[nC 光标右移n行
  • \033[nD 光标左移n行
  • \033[y;xH设置光标位置
  • \033[2J 清屏
  • \033[K 清除从光标到行尾的内容
  • \033[s 保存光标位置
  • \033[u 恢复光标位置
  • \033[?25l 隐藏光标
  • 0\33[?25h 显示光标

4.printf输出顺序

printf函数特性

  • 特性1:从后往前计算
  • 特性2:++/-- 在后面,表示真结束;
  • ++/--在前面,则表示假结束,需要将最后的结果输出
  • 特性3:输出的表达式若为赋值操作,则为假结束

示例1:

c 复制代码
#include <stdio.h>
int main(void)
{
	int z=4;
	printf("%d,%d,%d,%d,%d,%d,%d\n",--z,z--,z++,z=100,z++,++z,--z);
		                           //99 101 100  99    4   99  99						   
	/*
	printf函数特性
		1.先从右往左匹配,计算结束为假结束,但自增/自减在后面的表达式为真结束。
		2.再从左往右将值带入到所有假结束的表达式中,但不会对变量值做任何改变	
		上述打印可看做:printf("%d,%d,%d,%d,%d,%d,%d\n",A,B,C,D,E,F,G);
		首先从右往左计算:
			G=4-1=3 Z=3   
			F=3+1=4 Z=4   
			E=4     Z=Z+1=5   --真结束
			D=100   Z=100
			C=100   Z=Z+1=101  --真结束
			B=101   Z=Z-1=100  --真结束
			A=99    Z=Z-1=99
		因此,Z最终的结果为99

		再将Z的最终值,从左往右带入假表达式
			A=99
			B=101
			C=100
			D=Z=99
			E=4
			F=Z=99
			G=Z=99
	*/

示例2:

c 复制代码
	int x=10,y=20;
    printf("x++ + +=%d,x++= %d,++y=%d\n",x++ + ++y,x++,++y);
										//33       10   22
	/*
	上述打印可看做: printf("x++ + +=%d,x++= %d,++y=%d\n",A + B,C,D);
		从右往左带入:
			D=21 y=20+1=21
			C=10 x=10+1=11  -->真结束
			B=22 y=21+1=22
			A=11 x=11+1=12  -->真结束
		因此:x=12 y=22
		
		再将x、y的最终值,从左往右带入假表达式
		A+B=11+22=33
		C=10
		D=22
		
	*/																
}

示例3:

c 复制代码
#include <stdio.h>
int main()
{
	int arr[]={12,34,65,76,88,99};
	int *p=arr;
	//printf("%d %d %d\n",*p++,++*p,*p++);
						//35  35	12 
	printf("p=%p\n",p);
	//printf("%p %p %p %p\n",p++,++p,p+1,p++);
	/*
		printf("%p %p %p %p\n",p++,++p,p+1,p++);看做
		printf("%p %p %p %p\n",A,B,C,D);
		第一步:从后往前计算,根据++/--特性判断真假结束:
			D=arr -->  p=arr+1  -->真结束
			C=arr+2 -->p=arr+1  -->真
			B=arr+2 -->p=arr+2  -->假  --最后结果:arr+3
			A=arr+2 -->p=arr+3  -->真
	*/
	printf("%p %p %p\n",p++,p=&arr[4],p++);
	/*					A       B      C
		C=arr p=arr+1 -->真
		B=arr+4 p=arr+4 -->假  最后结果:p=arr+5
		A=arr+4 p=arr+5 -->真
		
		p=0x7fff28547e20
		0x7fff28547e30 0x7fff28547e34 0x7fff28547e20
	*/
	/* 
		printf 输出特性:
				特性1:从后往前计算
				特性2:++/-- 在后面,表示真结束;
					   ++/--在前面,则表示假结束,需要将最后的结果输出
				特性3:输出的表达式若为赋值操作,则为假结束
	*/
}

示例4:

c 复制代码
#include <stdio.h>
int main()
{
	int x=10,y=20;
	printf("%d %d %d %d %d %d %d %d\n",x=100,x++ + ++y,x+y,++x,y++,x++,++y,x+5);
	/*								    B     A       C   D   E   F   G   H
		H=15 x=10
		G=21 y=21 假  
		F=10 x=11 
		E=21 y=22
		D=12 x=12 假
		C=12+22=34 
		A=12+23=35  x=13 y=23
		B=100 
		100 35 34  100 21  10 23 15
	*/
	int arr[]={12,34,6,87,98,200};
	int *p=arr;
	printf("arr=%p\n",arr);
	printf("%p %p %d %d\n",p++,++p,*p,*p++);
	/*                      A  B    C   D
		D=12 p=arr+1
		C=34 p=arr+1
		B=arr+2 p=arr+2  假  -->arr+3
		A=arr+2 p=arr+3 
	
		arr+2   arr+3 34 12
	
		arr=0x7fffdf4837f0
		0x7fffdf4837f8 0x7fffdf4837fc 34 12
	*/
}
相关推荐
代码雕刻家8 小时前
1.9.课设实验-数据结构-图-校园跑最短路径
c语言·数据结构·算法·图论
吃好喝好玩好睡好9 小时前
OpenHarmony混合开发实战指南
c语言·python·flutter·vr·visual studio
laocooon5238578869 小时前
C语言,少了&为什么报 SegmentationFault
c语言·开发语言
white-persist9 小时前
【攻防世界】reverse | re1-100 详细题解 WP
c语言·开发语言·网络·汇编·python·算法·网络安全
CHANG_THE_WORLD9 小时前
Python 中的循环结构详解
开发语言·python·c#
程序员-周李斌9 小时前
ConcurrentHashMap 源码分析
java·开发语言·哈希算法·散列表·开源软件
JS_GGbond9 小时前
JavaScript入门学习路线图
开发语言·javascript·学习
quikai19819 小时前
python练习第一组
开发语言·python
BD_Marathon9 小时前
【JavaWeb】JS_JSON在客户端的使用
开发语言·javascript·json