C语言理解 —— printf 格式化输出


printf 函数

在软件开发过程中,通常需要打印一些字符串信息,或把一些变量值输出到上位机显示。打印函数printf是最常用的。

本文章的代码已在Dev-C++、Keil软件上运行,数据类型运算结果跟编译器有关

一般格式:

printf(格式控制字符串,输出值参数表);
  • 格式控制字符串

可以由三类字符(格式字符,转义字符,普通字符)组成。

格式字符 —— 由“%”引导,如%d、%f 等。作用是控制输出字符的格式。
转义字符 —— 转义字符按照转义后的含义输出,换行符“\n”,即输出回车。
普通字符 —— 原样输出的字符。

int sum = 0;
float temp = 0.314;
printf("sum=%d,temp=%f\n",sum,temp);
格式字符:%d和%f
转义字符:\n
普通字符:sum=,和temp=
  • 输出值参数表

1、可以是常量、变量或表达式。
2、输出值参数之间用逗号分隔,其类型应与格式字符相匹配。
3、每个格式字符和输出值参数表中的输出值参数必须一一对应。
4、没有输出参数时,格式控制字符串中不再需要格式字符,如:

printf("Are you OK?\n");

格式字符表

格式字符描述
d输出带符号的十进制整数,正数的符号省略,负数的符号正常输出
u以无符号的十进制整数形式输出
o以无符号的八进制整数形式输出,不输出前导符0
x以无符号十六进制整数形式(小写)输出,不输出前导符0x
X以无符号十六进制整数形式(大写)输出,不输出前导符0X
f以小数形式输出单、双精度数,隐含输出6位小数
e以指数形式(小写e表示指数部分)输出实数
E以指数形式(大写E表示指数部分)输出实数
g自动选取f或e中输出宽度较小的一种使用,且不输出无意义的0
c输出一个字符
s输出字符串

格式修饰符

格式修饰符描述
l修饰格式字符d、u、o、x时,用于输出long型数据
L修饰格式字符f、e、g时,用于输出long double型数据
h修饰格式字符d、o、x时,用于输出short型数据
输出域宽m(m为整数)指定输出项输出时所占的列数
显示精度.n(n为整数)对于实数,表示输出n位小数;对于字符串,表示截取的字符个数
-(减号)输出数字或字符在域内向左靠

一、短整型输出

  • d 格式字符
#include <stdio.h>
int main()
{
	short i = 2;
	int j=-68;
	long d = 0;
	d = i * 65536;
	printf("d = %ld\r\n",d);
	printf("j = %d\r\n",j);
	printf("size: i(%d)--d(%d)\r\n",sizeof(i),sizeof(d));
	return 0;
}

在这里插入图片描述
单字节变量用整型格式输出,最好加强制转换

#include <stdio.h>
int main()
{
	unsigned char i=0x51;
	printf("i = %d\r\n",(unsigned short)i);
	printf("size: i(%d)\r\n",sizeof(i));
	return 0;
}

在这里插入图片描述
无符号整型格式输出

#include <stdio.h>
int main()
{
	unsigned int i=168;
	printf("i = %u\r\n",i);
	printf("size: i(%d)\r\n",sizeof(i));
	return 0;
}

二、长整型输出

一个设备的序列号是9位数字,比如100000151,那么它对应的十六进制是0x05F5E197。

从设备读出序列号并存到数组里。

unsigned char serial[4];

serial[3] = 0x05;
serial[2] = 0xF5;
serial[1] = 0xE1;
serial[0] = 0x97;

将序列号以十六进制和十进制从串口打印出来。

#include <stdio.h>
int main()
{
	unsigned char serial[4]={0x97,0xE1,0xF5,0x05};
	unsigned long earbud_serial = 0;
	
	earbud_serial +=  ((unsigned long)serial[3]) << 24;
	printf("serial: 0x%08lX - %lu\r\n",earbud_serial,earbud_serial);
	earbud_serial +=  ((unsigned long)serial[2]) << 16;
	printf("serial: 0x%08lX-%lu\r\n",earbud_serial,earbud_serial);
	earbud_serial +=  ((unsigned long)serial[1]) << 8;
	printf("serial: 0x%08lX-%lu\r\n",earbud_serial,earbud_serial);
	earbud_serial +=  (unsigned long)(serial[0]);
	printf("serial: 0x%08lX-%lu\r\n",earbud_serial,earbud_serial);
	return 0;
}

在这里插入图片描述
打印unsigned long变量,在keil中第一条运算需要把d强制转换成unsigned long

#include <stdio.h>
int main(void)
{
	unsigned int mv = 780;
	unsigned char pc = 30;
	unsigned int d = 725;
	unsigned long tempv = 0;
	unsigned char ret = 0;

	tempv = 10 * pc * (unsigned long)d;printf("%lu ",tempv);
	tempv = tempv/mv;printf("%lu ",tempv);
	tempv = tempv + 5;printf("%lu ",tempv);
	ret = 0 + (unsigned char)(tempv/10);printf("%d \r\n",(unsigned short)ret);
}

三、浮点型输出

输出一个实数(包括单精度、双精度、长双精度),带有小数输出。

  • 基本型,%f

不指定输出数据的长度,由系统根据数据的实际情况决定数据所占的列数。

#include <stdio.h>
int main(){
	float f = 3.0;
	double df = 1.0;
	printf("f=%f,df=%f\n",f/3,df/6);
	return 0;
} 

在这里插入图片描述

实数中的整数部分全部输出,小数部分只输出6位。

  • 输出数据的宽度和小数位数,%m.nf

m表示输出数据的宽度,占多少列,n表示小数点后保留n位小数。
若不需强调输出数据宽度,可直接用%.nf

#include <stdio.h>
int main(){
	double a = 1.0;
	printf("%20.15f\n",a/3);
	return 0;
} 

在这里插入图片描述

在0前面有3个空格,小数点后输出了15位小数。
一个double型数只能保证15位有效数字的精确度,即使指定小数位数为50(如用%.50f),也不能保证输出的50位都是有效数值。

  • 输出的数据向左对齐,%-m.nf

加一个负号,能够让输出数据在域内向左靠齐

#include <stdio.h>
int main(){
	double a = 1.0;
	printf("%-8.15f\n",a/3);
	return 0;
} 

四、字符型输出

  • c 格式字符

输出一个字符,可以对照ASCII码表

#include <stdio.h>
int main(){
	char ch = 'e';
	char c = 0x54;
	printf("%c,%c",ch,c);
	return 0;
} 

在这里插入图片描述
也可以加格式修饰符指定域宽

#include <stdio.h>
int main(){
	char ch = 'e';
	char c = 0x54;
	printf("%6c,%c",ch,c);
	return 0;
} 

在这里插入图片描述

五、字符串输出

  • s 格式字符

输出一个字符串

#include <stdio.h>
int main(){
	printf("%s","are you ok?");
	return 0;
} 

在这里插入图片描述

六、注意问题

1、当格式控制字符串中没有%引导的格式字符时,则不需要有输出值参数表,直接输出字符串内容,转义字符按照转义后的实际意义输出

#include <stdio.h>
int main(){
	printf("nice to meet you!");
	printf("\n");
	printf("Hello,\ngood\t!");
	return 0;
}

在这里插入图片描述
2、当格式控制字符串中有%引导的格式字符时,则输出值参数表中的数量以及类型必须和格式字符一致,否则输出无法达到预期

#include <stdio.h>
int main(){
	int a = 158;
	double b = 16.8,c = 1.0;
	
	printf("a = %d,b = %d\n",a,b);
	printf("a = %d,c = %f\n",a);
	return 0;
}

在这里插入图片描述

第一个printf函数中的输出参数b是double型,但对应的格式控制符为%d,当类型不一致时并不会进行类型转换,而会将实际转入的double型值当作需要的整形类型来理解,因此出现非预期结果;
第二个printf函数中,格式控制字符串给出了两个%引导的格式字符,但是输出参数表中只有一个参数a。因此输出c的值默认为内存中a变量后面存储单元的数据值,即c的值不能确定。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值