知识点一:scanf函数使用公式
1)scanf是一个变参函数;
2)scanf的第一个参数是字符串;
scanf("%hhd %hd %d %ld %f %lf",&a,&b,&c,&d,&e,&n);
3)scanf的第一个参数内容为匹配字符以及转换规范;
scanf("%hhd %hd %d %ld %f %lf",&a,&b,&c,&d,&e,&n);\\算引号里面是需要输入的字符串以及转换规范
#请注意:输入时,需要按照第一个字符串的形式进行输入,否则无法得到正确结果;
例1:
scanf第一个字符串为 "%hhd %hd %d %ld %f %lf" ,每个转换规范使用空格分割。那么输入时需要用空格 进行分割,形如 1 2 3 4 5.6 7.8 ;
例2:
scanf第一个字符串为 "%hhd,%hd,%d,%ld,%f,%lf" ,每个转换规范使用 , 分割。那么输入时需要用逗号进 行分割,形如 1,2,3,4,5.6,7.8;
例3:
scanf第一个字符串为 "%hhd+%hd-%dx%ld/%f~%lf" ,转换规范使用+-x/~分割。那么需要像这样输 入 1+2-3x4/5.6~7.8;
4)scanf的后续参数,是转换完成后,数据的存放位置;
a)如果scanf将转换后的二进制存储到基本变量当中,请在变量名前加&;
b)如果scanf将字符串存储到字符数组中,字符数组名不用加&;
5)转换规范的写法与数量,需要与后续的参数类型和数量对应;
a)hhd对应char;
b)hd对应short;
e)d对应int;
d)ld对应long;
e)f对应float;
f)lf对应double;
知识点二:scanf函数的用处
1)将输入字符串与第一个参数进行匹配(首先,scanf函数读取到输入的字符串。接着,scanf会将这个输入字符串与第一个参数的字符串进行匹 配,找到输入字符串中的子串与转换规范的一一对应关系);
2)根据转换规范将字符转换为二进制(子串与转换规范匹配好之后就开始转换环节。scanf将根据子串对应的转换规范,使用不同的转换方 式,将子串转换为二进制);
长度指示符 | 转换规范 | 转换为某种类型的二进制 |
hh | d | char |
h | d | short |
无 | d | int |
l | d | long |
ll | d | long long |
hh | u | unsigned char |
h | u | unsigned short |
无 | u | unsigned int |
l | u | unsigned long |
ll | u | unsigned long long |
无 | f | float |
l | f | double |
无 | c | 字符对应的 ASCLL码表 |
无 | s | 字符串中字符对应的ASCII码 |
scanf("%hhd %hd %d %ld %f %lf",&a,&b,&c,&d,&e,&n);
子串 "1" 对应转换规范 "%hhd" ,将转换为char类型的二进制表示,1字节
子串 "2" 对应转换规范 "%hd" ,将转换为short类型的二进制表示,2字节
子串 "3" 对应转换规范 "%d" ,将转换为int类型的二进制表示,4字节
子串 "4" 对应转换规范 "%ld" ,将转换为long类型的二进制表示,4字节
子串 "5.6" 对应转换规范 "%f" ,将转换为float类型的二进制表示,4字节
子串 "7.8" 对应转换规范 "%lf" ,将转换为double类型的二进制表示,8字节
3)将转换后的二进制放入变量;
知识点三:几类错误示范
1)长度正确但类型错误;
#include <stdio.h>
int main()
{
long long ll;
scanf("%lf", &ll);
printf("%lld\n", ll);
printf("%f\n", ll);
return 0;
}
#我们输入了字符串 "123.45" ,该字符串被转换规范 "%lf" 匹配。 接下来,字符串 "123.456" 将被转换为double类型的二进制表示,8个字节。 最后,这8个字节被送给了 long long 类型的变量 ll 。 现在变量ll是一个装有double类型二进制的整型了。 我们使用 %d 来打印ll肯定出现了错误的结果。 那我们使用 %f 来打印呢? %f 将取8个字节的二进制,并且按照double类型二进制规则进行转换。结果 就得到了正确的结果。
2)输入字符串数值大于转换类型取值范围;
#include <stdio.h>
int main()
{
short s;
scanf("%hd", &s);
printf("%d\n", s);
return 0;
}
#我们输入了字符串 "2147483467" ,该字符串被转换规范 "%hd" 匹配。 接下来,字符串 "2147483467" 将被转换为short类型的二进制表示,2个字节。 而short类型的取值范围为 -32767~32768 , 2147483467 无法用short装下。 所以,无法得出正确的结果。
3)变量放不下转换结果;
#include <stdio.h>
int main()
{
short s;
scanf("%d", &s);
printf("%d\n", s);
return 0;
}
#我们输入了字符串 "2147483467" ,该字符串被转换规范 "%d" 匹配。 接下来,字符串 "2147483467" 将被转换为int类型的二进制表示,4个字节。 最后,转换后的4个字节的数据被short类型的变量s接收,丢失了2个字节。 所以,无法得出正确的结果。
4)如何避免错误;
#include <stdio.h>
int main()
{
int n;
scanf("%d", &n);
printf("%d\n", n);
return 0;
}
#我们输入了字符串 "2147483467" ,该字符串被转换规范 "%d" 匹配。 接下来,字符串 "2147483467" 将被转换为int类型的二进制表示,4个字节。 最后,转换后的4个字节的数据被int类型的变量n接收。 正确结果。
@@使用scanf的时候请注意,输入字符串的数值与转换规范和接收转换结果的变量类型必须匹配才能得到 正确结果。
知识点四:字符和字符串
1)输入字符;
#include <stdio.h>
int main()
{
char c;
scanf("%c", &c);
printf("%d %c\n", c, c);
return 0;
}
#我们输入了字符串 "A" ,该字符串被转换规范 "%c" 匹配。 接下来,字符串 "A" 将被转换为char类型的二进制表示(其十进制为65),1个字节。 最后,转换后的1个字节的数据被char类型的变量c接收。 当我们用 %d 打印c时,输出了数值 65 。而用 %c 打印时,输出了字符 A。
#include <stdio.h>
int main()
{
char c;
scanf("%hhd", &c);
printf("%d %c\n", c, c);
return 0;
}
2)输入字符串;
#include <stdio.h>
int main()
{
char str[10];
scanf("%s", str);
printf("%s", str);
return 0;
}
#c语言中没有字符串变量,字符串被存储在字符数组当中。 由于这里是将输入的字符串存储到字符数组中,后面的参数str不加&。 目前我们还没有讨论过数组,暂时不继续展开这一部分内容。
知识点五:scanf函数与printf函数不同
1)printf函数后续参数不需要加&,而scanf由于需要一个地址,所以对于基本变量需要加&,数组则不需要;
2)printf的参数由于比int小的变量会升级为int,float会升级为double。所以,转换规范d可以用于 char,short,int。转换规范f可以用于float和double。但是scanf是直接把转换结果送到接收变量中,必须严格使用转换规范。