赋值函数scanf:
scanf 的功能用一句话来概括就是“通过键盘给程序中的变量赋值”。
scanf函数的两种主流应用格式:
1) scanf("输入控制符", 输入参数);功能:将从键盘输入的字符转化为“输入控制符”所规定格式的数据,然后存入以输入参数的值为地址的变量中。
例程:
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
int main()
{
int a = 0;
int b = 0;
int sum = 0;
scanf("%d %d",&a, &b);
//%和d之间不能有空格,不然程序可以跑通 但是无法实现求和。
//【%d】之间不能有逗号,如果要加逗号 一定要加英文
//输入控制符之间如果要加逗号 逗号是需要原样输入的。
sum = a + b;
printf("sum=%d\n",sum);
return 0;
}
运行结果:
%d
输入控制符”和“输出控制符”是一模一样的。比如一个整型数据,通过 printf 输出时用%d
输出,通过 scanf 输入时同样是用%d
。
对于该代码,首先要清楚的是:我们从键盘输入的全部都是字符。比如从键盘输入 123,它表示的并不是数字 123,而是字符 '1'、字符 '2' 和字符 '3'。操作系统内核就是这样运作的。操作系统在接收键盘数据时都将它当成字符来接收的。这时就需要用“输入控制符”将它转化一下。%d
的含义就是要将从键盘输入的这些合法的字符转化成一个十进制数字。经过 %d 转化完之后,字符 123 就是数字 123 了。
&
第二个要弄清楚的是:&
是一个取地址运算符,&
后面加变量名表示“该变量的地址”,所以&i
就表示变量 i 的地址。&i
又称为“取地址i”,就相当于将数据存入以变量 i 的地址为地址的变量中。
所以程序中 scanf 的结果就把值 5 放到变量a中,6放入变量b中。
综上所述,scanf 语句的意思就是:从键盘上输入字符 5和6,然后%d
将这两个字符转化成十进制数 5和6,最后通过“取地址 a”“取地址b”找到变量a和b的地址,再将数字 5和6 放到以变量 a和b的地址为地址的变量中。
注意,为什么不直接说“放到变量a,b中”?而是说“放到以变量 a,b 的地址为地址的变量中”?因为这么说虽然很绕口,但是能加强对 &a &b的理解,这么说更能表达 &a &b的本质和内涵。
2) scanf("输入控制符非输入控制符", 输入参数);
这种用法几乎是不用的,也建议你们永远都不要用。但是经常有人问,为什么 printf 中可以有“非输出控制符”,而 scanf 中就不可以有“非输入控制符”。事实上不是不可以有,而是没有必要!
下面来看一个程序:
# include <stdio.h>
int main(void)
{
int i;
scanf("i = %d", &i);
printf("i = %d\n", i);
return 0;
}
直接键盘输入一个十进制字符,例如5:运行结果为:
可见键盘输入的字符5并没有被放入地址i中。
程序中为什么 i=-858993460?
因为:对于未初始化的变量,它的值可能是不固定的垃圾值,也有一些编译器会自动将一个很小的数字(比如 -858993460)设置为该变量的值。
造成这个结果的原因如下:
在 printf 中,所有的“非输出控制符”都要原样输出。同样,在 scanf 中,所有的“非输入控制符”都要原样输入。所以在输入的时候i=
必须要原样输入。比如要从键盘给变量 i 赋值 123,那么必须要输入i=123
才正确,少一个都不行,否则就是错误。
对键盘输入作更正:
所以 scanf 中%d
后面也没有必要加\n
,因为在 scanf 中\n
不起换行的作用。
所以在 scanf 的使用中一定要记住:双引号内永远都不要加“非输入控制符”。除了“输入控制符”之外,什么都不要加,否则就是自找麻烦。而且对于用户而言,肯定是输入越简单越好。
一次给多个变量赋值:
# include <stdio.h>
int main(void)
{
int i, j;
scanf("%d%d", &i, &j);
printf("i = %d, j = %d\n", i, j);
return 0;
}
运行结果如下:
首先,scanf 中双引号内除了“输入控制符”之外不要加任何“非输入控制符”。通过键盘给多个变量赋值与给一个变量赋值其实是一样的。比如给两个变量赋值就写两个 %d,然后“输入参数”中对应写上两个“取地址变量”;给三个变量赋值就写三个 %d,然后“输入参数”中对应写上三个“取地址变量”……
但是需要注意的是,虽然 scanf 中没有加任何“非输入控制符”,但是从键盘输入数据时,给多个变量赋的值之间一定要用空格、回车或者 Tab 键隔开,用以区分是给不同变量赋的值。而且空格、回车或 Tab 键的数量不限,只要有就行。一般都使用一个空格。
即使两个%d之间没有空格 键盘输入字符时一定要用空格
此外强调一点:当用 scanf 从键盘给多个变量赋值时,scanf 中双引号内多个“输入控制符”之间千万不要加逗号,
。
有些人觉得在输入的时候可以用逗号分隔,所以就在“输入控制符”之间用逗号隔开。这样做从程序的角度确实是可以的,但是建议大家不要这样做。在实际编程中这种写法是绝对不允许的,原因有两个:
- 首先逗号要原样输入的,有几个就要输入几个,少一个或多一个都不行;
- 其次,也是最主要的原因就是输入法的问题,在 scanf 中是在英文输入法下写的逗号,那么输入的时候如果是中文输入法下的逗号那也是错的。所以用逗号很容易出错。
如图所示:
最后再次强调:scanf“输入参数”的取地址符&
千万不要忘了。而 printf 中的“输出参数”是不带取地址符的,不要混淆了。
优化: 在使用 scanf 之前使用 printf 提示输入
大家想一想,前面写的 scanf 程序有没有不足的地方?
程序写好之后,编译、链接、执行,然后弹出黑窗口,出现一个光标在那不停地闪。对于编写程序的人来说他知道要输入什么,但是对于用户而言,用户怎么知道是什么意思呢?所以之前的程序都缺少提示信息!因此在使用scanf之前,最好先用printf提示用户以什么样的方式输入,这样可以大大提高代码的质量。看看下面这个程序:
int main(void)
{
int i, j;
printf("请输入两个值,中间以空格分隔:");
scanf("%d%d", &i, &j);
printf("i = %d, j = %d\n", i, j);
return 0;
这样在执行的时候,用户一看就知道是要输入两个值,然后中间用空格隔开。所以这样写就更人性化、智能化了。
小结
scanf 的使用看似细节繁杂,但使用起来非常简单。就目前而言,只要掌握以下五点:
- 在 scanf 的“输入参数”中,变量前面的取地址符
&
不要忘记。 - scanf 中双引号内,除了“输入控制符”外什么都不要写。
- “输出控制符”和“输出参数”无论在“顺序上”还是在“个数上”一定要一一对应。
- “输入控制符”的类型和变量所定义的类型一定要一致。对于从键盘输入的数据的类型,数据是用户输入的,程序员是无法决定的,所以在写程序时要考虑容错处理,这个稍后再讲。
- 使用 scanf 之前先用 printf 提示输入。