在上文中,我们学习了使用printf和putchar输出数据,现在我们就来看看如何输入数据。
和printf、putchar很相似,我们可以使用scanf和getchar来输入数据
getchar的字面意思就是get(获取)一个char,这个函数他将返回一个整型的数据,这是你从屏幕中输入的字符的ascii码,你可以使用整型或者字符型来接收。
请尝试下面的程序
#include <stdio.h> int main() { char ch; ch = getchar();//用ch去接受字符 putchar(ch);//将字符显示出来 return 0; }
请亲自运行这个程序。你会发现它启动后并不像我们之前的程序,黑色的窗口内一个字符也没有显示
当然,这是因为我们使用了一个getchar,它在等待我们输入数据。如果我们就这样瞄着屏幕哈气,那么程序也会不鸟你(除了光标还在一闪一闪的,告诉你“我正在运行”)
现在,请按下屏幕上任意一个字符键,切记是字符键(就是a-z,0-9和其他所有的标点符号)
很明显,屏幕里出现了一个字符,他就是我们刚刚通过键盘输入的
但是如果你看懂了前一节的的话,或许会问到【你用putchar输出的字符呢】
答案是getchar还在等我们输入!
要验证这个很简单,我们只需要再按另一个键
你会发现它会跟在a后面显示出来,这说明getchar还在等待我们输入(难道getchar可以一次输入多个字符?可是我们只用了一个char变量去接受它啊)
【你骗我,你个坏淫!说好了输入字符的呢!】
我可没骗你,要让getchar得到字符,只需要你按一下回车键
程序就退出了,而且在第二行显示了我们一开始输入的字符a
为什么会这样呢。要说明白这个,就不得不讲到一个叫做“缓冲区”的东西了
如果把缓冲区放在本文中讲,就会显得太长。而且重点也比较分散、同时也加大了难度。于是我将它单独放到了一篇文章中 http://yangwang.hk/?p=315 。如果你比较急,可以现在把它看完。或者留在本篇文章看完后再浏览。如果你觉得内容太困难(新手理解起来确实有难度),往后放放也行,它并不会对我们后面的学习有太大的影响!
总之,我们只需要知道,直接从键盘中输入的数据,不会被getchar立即得到。而是等你在按下回车之时,getchar才会get到一个字符,然后将它传回来。
scanf
scanf就是scan(扫描)+format(格式化),即格式化输入函数
scanf的用法就要比getchar复杂多了。不过他和printf差不多,它们是一家子,一个是输入,一个是输出。
scanf的参数和printf长得也差不多(就像龙凤胎一样),他的参数也分两部分,一个是字符串类型的格式控制参数,在格式控制参数的后面,跟的是“可变”个数的保存数据的变量(参数个数根据格式控制参数而改变)
刚才的程序改为scanf后长这样
#include <stdio.h> int main() { char ch; scanf("%c", &ch); //使用scanf输入一个字符 putchar(ch); return 0; }
请尝试运行这个程序,他和上面的版本在操作上没有什么不同,如果你一股脑的输入数据而不按回车的话,scanf什么也得不到。
知道你按下回车的那一刻,scanf才会着手开始处理你输入的数据,并且将值保存在变量ch中。
getchar使用起来很简单,但是功能也很简单,它一次只能获取一个字符,而且还是ascii码。而scanf用起来似乎难度大一些,但是功能比getchar要强大得多。
我们现在把上面的程序中scanf那句抠出来放在这儿,来方便我们的讲解。
scanf("%c", &ch);
“%c”就是格式控制参数,它看起来和printf差不多,实际上他就是将printf反过来。printf打印数据到屏幕,scanf则从“屏幕”上(准确说是输入缓冲区)取回数据到变量。
%c这个占位符告诉scanf,我们需要输入的是一个字符型数据,不是十六进制整数,更不是十进制浮点数。
后面的ch则是保存输入数据的变量。这一切都和printf相同,除了ch前面多加了个&
&在c语言中是“取址符”,作用是获取一个变量的(内存)地址。
这就像你家的地址一样,通过这个地址,我可以找到(访问)你。
scanf就像一个送快递的,我们输入的数据就是快递。
当我们需要把快递送给xxx时,就需要在运单上填好xxx的地址,scanf这个快递员便会根据这个地址把快递放到xxx家。
如果你只写了收件人是xxx(写变量名),不给地址,那么快递员肯定会给你两巴掌。因为xxx是一个人,鬼知道他在哪儿!(变量名代表的是数值)
至于发快递的时候(printf输出的时候),就没有这么麻烦了。printf就像是一个收件的员工。你到快递网点发快递时,只需要把快件(数据)交给他就好了,鬼去管你家住哪儿(其实还是需要发件人地址,退回的时候用啦)。因此就用不着取址符。如果你在printf里用了取址符,那么它输出的就不是数据而是变量的地址了!
下表是scanf的部分占位符
字符 | 对应的数据类型 | 含义 |
i | int | 输入八进制、十六进制、十进制整数 |
d | int | 输入整型数值 |
o | unsigned int | 输入8进制整数 |
u
|
unsigned int | 无符号10进制整数 |
x / X
|
unsigned int | 无符号16进制整数,x对应的是abcdef,X对应的是ABCDEF(不输出前缀0x) |
f(lf)
|
float(double) | 单精度浮点数用f,双精度浮点数用lf |
e / E
|
double | 输入科学计数法表示的数,此处”e”的大小写代表在输出时用的“e”的大小写 |
g / G
|
double | 同上 |
c
|
char | 输入字符型 |
s / S
|
char * | 输出字符串 |
请看下面的程序
#include <stdio.h> int main() { int intdata; double doubledata; scanf("%d%lf", &intdata, &doubledata); printf("%d\n%f", intdata, doubledata); return 0; }
这个程序将输入一个int数据,和一个double数据,并且将它显示出来
使用时,先输入第一个数据(一个整数),然后按回车
接着输入第二个第二个浮点型数据,再按回车
现在请自己写一个“计算”程序
输入两个浮点型数据,然后打印出他们的和
答案将在下一篇文章中揭晓