- 说明:控制输出的字符组成字符串
- 若有多个数值/表达式使用逗号分隔
- 调用格式:printf("格式控制",输出项表)
- 格式控制字符串:使用一对双引号括起来的,作用是将数据从二进制转换成指定数据输出
- 格式控制字符串组成:格式说明符,附加格式说明符,转义字符和普通字符组成
- 格式说明符:由%和“格式字符”组成
格式字符:d、o、c、u、f、s等
6. 注意:格式说明符决定最终输出格式。前后的个数,顺序,类型应保持一致,通常用小写字母表示,不一致将会导致输出错误的结果。
7. printf函数常用的格式字符,如下表:↓
格式字符 | 含义 |
d | 以十进制有符号形式输出整型数据(正整数不输出加号+)ps:数值过大会溢出,输出错误结果 |
o | 以八进制无符号形式输出整型数据(不输出前缀o) |
X/x | 以十六进制无符号形式输出整型数据(不输出前缀0x),若位小x则输出小写十六进制数符 a~f,若为大X 则输出大写十六进制数符 A~F |
u | 以十进制无符号形式输出整型数据 |
f | 以小数形式输出实型数据(包括单精度实型和双精度实型),小数部分保留6位 |
E/e | 以指数形式输出实型数,小数部分保留6位 |
G/g | 以f或e格式中宽度较短的一种格式输出实型数据(短实型),不输出无意义的0。在用G 时,若以指数形式输出则指数以大写E表示,在用g时,用小写e表示 |
c | 以字符形式输出,只输出一个字符(ps:若有多个字符则输出最前面那一个)只占一列宽度 |
s | 输出字符串 |
注:在计算机内部,除十进制以外,其他进制都以补码的形式存储,所以其他进制的格式字符是无符号的,负数也认为是正数(负数通常使用二进制补码表示,而正数使用二进制原码表示)
8. 附加格式说明符:在“%”和“格式说明符”之间还可以加入附加格式说明符,以说明输出数据的标志、域宽(所占列数)、精度和长度修饰符。
- printf函数常用的附加格式说明符,如下表:↓
附加格式说明符 | 含义 |
l(小写唉喽) | 在格式字符 d、o、x、u之前,输出长整型数据。在格式字符 e、f、g之前,输出双精度实型数据(%ld、%lf) |
h | 输出短整型数据,可用在格式字符 d、o、x、u之前(%hd) |
m(正数) | m表示输出数据所占的域宽,也就是占几个字符位的宽度。(%mld) 当输出数据宽度小于 m且m为正时,输出的数据或字符右对齐,左边补空格;当m为负时,输出的数据或字符左对齐,右边补空格。当输出数据宽度大于m时,按实际宽度输出 |
n(正整数) | 当输出实型数据时,表示输出n 位小数;当输出字符串时,表示截取前n 个字符输出(%.2f) |
-(负) | 输出的数据或字符在域内左对齐 |
+(正) | 指定在有符号数的正数前面显示正号 |
0 | 输出数值时指定左侧的空位自动置0 |
# | 在八进制和十六进制数前显示前缀0和0x |
注:%md:正数前面空格,负数后面空格。(正右负左)
9. 常用的输出格式,如下表↓
数据类型 | 输出格式 |
有符号整型数据 | %d |
有符号长整型数据 | %ld |
实型数据 | %m.nf(m为域宽,n为保留几位小数,f为输出实型数据) |
字符串数据 | %s |
无符号整型数据 | %u |
无符号长整型数据 | %lu |
字符型数据 | %c |
10. 例题:int a=123,b=12345;printf("a=%4d\nb=%4d\n",a,b);的输出结果为?
- %4d意思为:输出占4个字符宽度的十进制整型数据
- 其中a=123只有3个数据,不够,数据就靠右边对齐,左边补空格
- 而b=12345有5个数据,超过限定域宽,按实际长度输出
- 输出结果如下图:↓
- 11.例题:执行语句printf("%c",'A'+3); 后输出结果是 ?
- 分析:格式字符%c是只输出一个字符
- 那么会把'A'转换成对应的ASCII码值
- A=65,然后65+3=68
- 再把68转换成ASCII所对应的字符是'D'
- 12.例题:设int a,b,c;执行语句printf("%d",(a=1,b=2,c=3)); 后输出结果是?
- 分析:%d是以输出十进制整型数据
- (a=1,b=2,c=3)这是一个逗号表达式,结果为末尾数值c=3
- 所以输出结果为3
- 13.例题:已知字符'A'的ASCII码值是65,
且char c1='A',c2='D';
则执行语句printf("%d,%d\n",c1,c2-2); 后的输出结果是?
- 分析:%d是以输出十进制整型数据,所以会将字符转换成ASCII码值,A=65,D=68
- 所以c2-2=68-2=66
- 输出结果为68,66
- 14.例题:设int i=3,j=2;char k='a';
则执行语句printf("%c",k+i/j);后输出结果是?
- 分析:格式字符%c是只输出一个字符
- k+i/j表达式根据优先级先计算 / 再计算+
- i/j=3/2=1,将char k='a'转换成ASCII码值=97
- k+1=97+1=98→b
- 输出结果为b
- 15.例题:下列程序的输出结果是 ?
int a=1; int f () { int a=2;return a; } void main() { printf("%d,%d",a,f()) ; }
- 分析:
f()
函数在printf
函数之前被调用,但在之前没有声明或定义f()
函数。为了解决这个问题,可以在f()
函数之前提供一个函数声明或将f()
函数移至printf
之前
#include <stdio.h>
// 声明函数 f()
int f();
int main() {
int a = 1;
printf("%d,%d", a, f());
return 0;
}
// 定义函数 f()
//可以不带参数,返回时返回即可
//这种函数被称为无参数函数或空参数函数。
int f() {
int a = 2;
return a;
}
- 第一个%d占位符是a,第二个%d占位符是函数f()
- 所以输出结果为1,2
- 16.例题:设char ch='a';
执行printf("%d,%c\n",ch,ch+2);后的输出结果是?
- 分析:%d是ch的占位符,输出十进制整型
- 所以char ch='a'转换成ASCII码值=97
- %c是ch+2的占位符,输出一个字符
- ch+2=97+2=99→c
- 所以输出结果为97,c
- 17.例题:设char k='a';
float j=2.0;执行k+=5/j; printf("%c",k);后输出结果是?
- 分析:k+=5/j表达式根据优先级先计算 / 再计算+
- 所以k+=(5/j)=5/2.0=2.0
- char k='a'转换成ASCII码值=97
- k+=2.0→k=k+(2.0)=97+2.0=99.0
- 由于输出格式为%c,所以99.0→c
- 18.例题:设int a=-1,b=3;
执行语句printf("%d",a<b-2 || (b=-2));后b的值 ?
- 分析:a<b-2 || (b=-2)该表达式考虑优先级和短路问题
- 且短路问题高于优先级
- 所以a<b-2 →-1<2-2→-1<0结果为真
- 输出1
- 19.例题:设char str[]={'a','b','\n','c','d','\0'};
执行printf("%s\n",str);后输出结果是?
- 分析:%s是输出字符串
- str[]数组中'a','b','\n',\n的意思是换行
- 'c','d','\0'中\0是字符串的结束标志
- 所以输出结果为:ab换行cd
- 20.例题:执行语句printf("%x",-1); 后输出结果是 ?
- 分析:%x是以十六进制输出整型,且是小写
- -1转换成十六进制过程如下图:
- [ ] 1000 0000 0000 0001 (原码,最左边为符号位)
- [ ] 1111 1111 1111 1110 (反码,符号位不变其他位按位取反)
- [ ] 1111 1111 1111 1111 (补码=反码+1)
- [ ] 8+4+2+1=15
- [ ] 十六进制的15为f
- [ ] 所以输出结果是ffff
- 例题:执行语句printf("%d\n",1&2);后输出结果是 ?
- 分析:1&2是按位与,要转换成二进制位
- 0001 & 0010=0000=0
- 所以输出结果是0
- 21.例题:设float m=8.8;int n=6;
执行语句printf ("%d\n",(int) m+n) ;后输出的结果是?
- 分析:(int) m+n=(int)8.8+6=14强制转型
- 所以输出结果是14
- 22.例题:执行语句printf ("s\n","1+2+3\0=6") ;后输出结果是 ?
- 分析:s是输出字符串,由于\0是字符串的结束标志
- 所以输出结果是123
- 23.例题:设 char ch='b';
执行语句printf ("%c,%d\n",ch-32,ch) ;后输出的结果是?
- 分析:ch-32的占位符是%c
- char ch='b'转换成ASCII码值=98
- ch-32=98-32=66→B
- ch的占位符是%d,ch=98
- 输出结果是B,98
- 24.例题:执行语句printf("%s\n","World\0Wide\0Web");
后的输出结果是?
- 分析:s是输出字符串,由于\0是字符串的结束标志
- 遇到\0结束输出,所以输出结果是World
- 25.例题:设有char *a="ABCD",
则printf("%c",*a)的输出结果是?
- 分析:%c是只输出一个字符,若有多个只取开头第一个
- 所以输出结果是A
- 26.例题:设int n=10;
执行语句printf("%o,%x\n",n,n);后的输出结果是?
- 分析:%o是输出八进制整型数据
- 所以n=10转换成八进制=12
- %x是输出十六进制整型数据(且是小写)
- 所以n=10转换成十六进制:16/10=0......10→a
- 所以输出结果是12,a
- 27.例题:设int x=3;
执行printf("%d\n",x+(x-=x*x));后的输出结果是?
- 分析:x+(x-=x*x)为复合赋值表达式,需要进行扩展
- 先计算括号里的(x-=xx)→x=x-(xx)→x=x-3*3→x=3-9=-6
- 此时x=-6已经重新赋值
- 然后x+(-6)=(-6)+(-6)=-12
- 所以输出结果是-12
- 28.例题:设float x=23.65;
则执行语句printf("%d\n",(int)(x+0.5));后输出结果是?
- 分析:(int)(x+0.5)=(int)(23.65+0.5)=24.15=24
- 所以输出结果是24
- 29.例题:输入某学生的数学(math)、英语(english)和C语言(C)的成绩,输出该学生这三门课的成绩、总成绩(sum)和平均成绩(aver),数据类型为float
#include <stdio.h>
int main() {
float math, english, C, sum, aver;//定义变量
printf("请输入学生的数学,英语,C语言成绩:\n");//提示输入
scanf_s("%f,%f,%f", &math, &english, &C);//输入三科成绩
sum = math + english + C;//计算总成绩
aver = sum / 3;//计算平均成绩
printf("math=%.1f,english=%.1f,C=%.1f,sum=%.1f,aver=%.1f\n",math,english,C,sum,aver);
//输出结果
}
30.例题:
(1)编写函数fa,参数为float(float d,float h)计算并输出直角三角形的面积s1; (2) 编写函数fb,参数为(float a,float b,float c)计算并输出梯形的面积s2;
(3)编写主函数main,键入直角三角形的底 (d)和高 (h),调用函数a计算并输出该直角三角形的面积;键入梯形的上底 a)、下底 (b)和高 (c)调用函数fb计算并输出该梯形的面积。 (输出结果保留两位小数)
#include <stdio.h>
//int fa(float d, float h);
//int fb(float a, float b, float c);
//自定义函数写在最前面的时候可以不用在最开头和主函数中额外声明
int fa(float d, float h) {
float s1;
s1 = (d*h)*1.0 / 2;
printf("s1=%.2f\n", s1);
return s1;
}
int fb(float a, float b,float c) {
float s2;
s2 = (a + b)*c*1.0 / 2;
printf("s2=%.2f\n", s2);
return s2;
}
int main() {
float d, h,s1;
float a, b, c,s2;
printf("请输入三角形的底和高:\n");
scanf_s("%f%f", &d, &h);
s1=(fa(d, h));
printf("三角形的面积是:%.2f\n",s1);
printf("请输入梯形的上地,下底,高:\n");
scanf_s(" %f%f%f", &a, &b,&c);
s2 = fb(a, b, c);
printf("梯形的面积是:%.2f\n", s2);
return 0;
}