scanf的功能用一句话来概括就是“通过键盘给程序中的变量赋值”。该函数的原型为:
# include <stdio.h> int scanf(const char *format, ...);
它有两种用法,或者说有两种格式。
(1)scanf("输入控制符",输入参数);
功能:将从键盘输入的字符转化为“输入控制符”所规定格式的数据,然后存入以输入参数的值为地址的变量中。
下面给大家举个例子:
# include <stdio.h> int main(void) { int i; i = 10; printf("i = %d\n", i); return 0; }
我们前面都是像这样写的,即直接给变量i赋一个值。但是这样写功能比较弱,因为这个值就变成一个“死值”了,它只能是10,不可能是其他值,除非在程序中修改。很多时候我们希望这个值不是由程序员在程序中指定的,而是在程序运行的过程中由用户从键盘输入的。用户输入多少,变量i就是多少,这样程序的功能就更加灵活了。
那么如何实现在程序运行的过程中由用户从键盘输出值呢?用scanf即可实现:
# include <stdio.h> int main(void) { int i; scanf("%d", &i); //&i 表示变量i的地址,&是取地址符 printf("i = %d\n", i); return 0; }
“输入控制符”和“输出控制符”是一模一样的。比如一个整型数据,通过printf输出时用%d输出,通过scanf输入时同样是用%d。
要想将程序中的scanf行弄明白,首先要清楚的是:我们从键盘输入的全部都是字符。比如从键盘输入123,它表示的并不是数字123,而是字符'1'、字符'2'和字符'3'。这是为什么呢?操作系统内核就是这样运作的。操作系统在接收键盘数据时都将它当成字符来接收的。这时就需要用“输入控制符”将它转化一下。%d的含义就是要将从键盘输入的这些合法的字符转化成一个十进制数字。经过%d转化完之后,字符123就是数字123了。
第二个要弄清楚的是:&是一个取地址运算符,&后面加变量名表示“该变量的地址”,所以&i就表示变量i的地址。&i又称为“取地址i”,就相当于将数据存入以变量i的地址为地址的变量中。那么以变量i的地址为地址的变量是哪个变量呢?就是变量i。所以程序中scanf的结果就把值123放到变量i中。
综上所述,scanf语句的意思就是:从键盘上输入字符123,然后%d将这三个字符转化成十进制数123,最后通过“取地址i”找到变量i的地址,再将数字123放到以变量i的地址为地址的变量中,即变量i中,所以最终的输出结果就是i=123。
注意,为什么不直接说“放到变量i中”?而是说“放到以变量i的地址为地址的变量中”?因为这么说虽然很绕口,但是能加强对&i的理解,这么说更能表达&i的本质和内涵。很多人在学习scanf的时候,经常将“变量i”和“变量i的地址”混淆,从而思维开始混乱,等深刻了解&i的含义之后就可以不那么说了。
以上是scanf的最简单用法,也是最常用、最基本、最重要的用法。这样通过scanf就可以在程序运行的过程中由用户来指定变量i的值,这与在程序中赋值相比较功能更强大。
(2)scanf("输入控制符非输入控制符",输入参数);
这种用法几乎是不用的,也建议你们永远都不要用。但是经常有人问,为什么printf中可以有“非输出控制符”,而scanf中就不可以有“非输入控制符”。事实上不是不可以有,而是没有必要!下面来看一个程序:
# include <stdio.h> int main(void) { int i; scanf("i = %d", &i); printf("i = %d\n", i); return 0; }
在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键的数量不限,只要有就行。一般都使用一个空格。
此外强调一点:当用scanf从键盘给多个变量赋值时,scanf中双引号内多个“输入控制符”之间千万不要加逗号“,”。
有些人觉得在输入的时候可以用逗号分隔,所以就在“输入控制符”之间用逗号隔开。这样做从程序的角度确实是可以的,但是建议大家不要这样做。在实际编程中这种写法是绝对不允许的,原因有两个:首先逗号要原样输入的,有几个就要输入几个,少一个或多一个都不行;其次,也是最主要的原因就是输入法的问题,在scanf中是在英文输入法下写的逗号,那么输入的时候如果是中文输入法下的逗号那也是错的。所以用逗号很容易出错。
最后再次强调:scanf“输入参数”的取地址符“&”千万不要忘了。这是初学者经常犯的错误。而printf中的“输出参数”是不带取地址符的,不要混淆了。