一、printf函数
(一)基本用法
打印字符串
printf("字符串");
(二)占位符
如果我要打印"我今年20岁"
printf("我今年20岁\n");
但是人的年龄是会变的,20岁会变成21、22…怎么让他根据实际情况变换呢,就要用到占位符
printf("字符串混杂占位符%[]")
%是占位符的第一个字符,[]内的内容是占位符的类型,该类型取决于你想要输出的内容是什么数据类型。
就比如
int age = 20;
printf("我今年%d岁",age);
这里的%d
就是一个占位符,表示这里会有一个整型数据占位。
占位符有很多,一般数据类型有多少,就有多少占位符,还有一些特殊占位符。
常见的占位符:
- %d: 整型
- %hd:短整型
- %ld:长整型
- %c: 字符
- %s:字符串
- %f:单精度浮点型
- %lf:双精度浮点型
- %u:无符号整型
- %hu:无符号短整型
- %lu:无符号长整型
- %p:打印地址
- %x:打印十六进制数
多个占位符,有几个占位符,就有几个变量,占位符一一对应,如果占位符所对应的类型有错,则会打印随机值。
printf("%s今年%d岁\n","张三","30")
(三)指定数据宽度
printf("%[]d",变量)
[]内部是一个数,用于指定数据的最小长度,如果变量的值超过了该长度,不影响打印,一般用于对齐排头
printf("%10d\n%10d\n",123,4567)
这里不难看出来是右对齐,从对齐的字母向前数,一共由10个空位这就是%10d的含义,那左对齐呢,只需要在10前加一个负号就行
但是如果打印的数据超过限定的宽度,就起不到对齐作用,所以一般指定宽度大于数据长度。
(四)限定小数位数
printf(%.[]f)
[]内部是你希望保留的小数位数
%f默认会打印6位小数,不足则会补充0,限定小数可以是输出更简洁
printf("%.2f\n",3.1415);
二scanf函数
(一)基本用法
scanf("占位符",&变量);
scanf的作用是给变量输入一个值,&这个符号叫做取地址,每个变量都会有自己的存放地址,我们想要给变量赋值,首先得知道它在哪儿,所以要取地址。
#include <stdio.h>
int main()
{
int a = 0;
printf("请输入a的值:");
scanf("%d",&a);
printf("您输入的值为%d\n",a);
return 0;
}
(二)scanf读取原理与返回值
在上一个代码中,编译器会报一个警告,说我忽略了scanf的值,说明scanf他是有返回值的,实际上scanf的返回值是它所成功读取的变量的数量。
int main()
{
int ret = 0;
int a = 0, b = 0;
float c = 0.0;
printf("请输入a、b、c的值:");
ret = scanf("%d%d%f",&a,&b,&c);
printf("您输入的值为 a = %d\nb = %d\nc = %f\n",a,b,c);
printf("scanf的返回值是:%d", ret);
return 0;
}
注意scanf在输入值的时候,需要空格,scanf在处理数据时会自动过略空白内容,scanf会依次读取数据,首先读取到1这是和占位符相同的数据,但是后一个是空格表示已经结束第一个内容读取,紧接着读取第二个24,第三个4。这里我输入的是4,为什么输出确实4.000000呢,因为计算机会在赋值时,将低精度强制转化为高精度,小数的精确位数比整数高,赋值也是把4赋给了浮点数c,所以输出是小数形式。
那如果我输入时不空格。
int main()
{
int ret = 0;
int a = 0, b = 0;
float c = 0.0;
printf("请输入a、b、c的值:");
ret = scanf("%d%d%f",&a,&b,&c);
printf("您输入的值为 a = %d\nb = %d\nc = %f\n",a,b,c);
printf("scanf的返回值是:%d", ret);
return 0;
}
这里我输入一堆字符,按照读取原理,scanf先处理第一个%d对应的a,检索到12后,#不是整型,所以从12断开,把12赋给了a,而后检索第二个%d对应的b,从上次检索结束处重新开始检索,但是第二个也是整型与#不对应,所以此时检索错误,会结束检索,此处的值会被赋值为零,后面的值回事随机值,这里不是随机值,是因为我在创建变量时进行了初始化。
int main()
{
int ret = 0;
int a = 0 ;
char b;//将变量b改为字符型
float c = 0.0;
printf("请输入a、b、c的值:");
ret = scanf("%d%c%f",&a,&b,&c);
printf("您输入的值为 a = %d\nb = %c\nc = %f\n",a,b,c);
printf("scanf的返回值是:%d", ret);
return 0;
}
这个时候你输入12#345
如果在scanf没有成功读取任何数据之前就已经发生错误则会返回EOF(这是一个常量-1),就是我们的键盘对应的回车键。所以利用这个特性我们在一些oj比赛就可以写出这样的代码
while(scanf("%d",&a)!=EOF)
{
}//这是竞赛常用的代码
指定读取长度
字符串是存储与字符数组中的数据,但是数组的长度一般有限,scanf在输入字符串时如果超过了限制性航都,就会越界访问,编译器会报错,怎么解决这个问题。
char ch[5] ;//字符数组,有5个长度,最多只能存储5个数据,且字符串结尾必需有\0结尾,所以在输入时只能输入4个字符
scanf("%[]s",ch);//这里不用取地址,因为数组的名字本身就是一个地址(指针)。[]内就写你想要限定的字符长度
还是以这个代码为例
int main()
{
int ret = 0;
int a = 0;
char b[4];
float c = 0.0;
printf("请输入a、b、c的值:");
ret = scanf("%d%3s%f",&a,b,&c);
printf("您输入的值为 a = %d\nb = %s\nc = %f\n",a,b,c);
printf("scanf的返回值是:%d", ret);
return 0;
}
我就想解决输入12###345
对应的问题,那就把b改为一个字符串,并且要注意去越界问题,由于b只有4个长度,所以要限定读取3个字符,不然###345
会长处数组长度.