小刘又来到了熟悉的教室,开口道:“昨天我给大家讲了输出函数printf(),从参数、语法到格式符都领大家又学习了一遍。大家都理解了吗?”,同学们齐声说:“理解了。”这时小韩突发一句感慨:“原来短短一句printf()还包含了这么多东西,看来C语言并没有表面上那么“人畜无害”啊。”小刘笑道:“C语言可是编程语言里的“老大哥”,它的内容可还多着呢,今天就让我们再来学一学C语言中常用的输入函数scanf()。”
“学完了printf()作为基础其实再学scanf()就很简单了,我们先来看一下官方文档中对它的定义”,
官方文档:
“可以看到,scanf()的在语法上的定义是和printf()是一样的,也是一个指针变量常量,也就是说scanf()与printf()一样可以支持不同格式的变量传入到字符串中。但不同的是,在传入的变量前面必须加上‘&’,也就是取地址符。我们来看一个具体的例子:[code_1]”
//[code_1]
#include
int main()
{
int a;
char str[20];
scanf("%d",&a);
scanf("%s",&str);
return 0;
}
输出:
“可以看到上述代码中有两个输入函数scanf(),其中变量a是一个整型,输入之后按下空格或者回车输入另一个变量str,其中str是一个字符数组可以接收字符串型的变量,又因为数组的首元素就是数组所在的首地址,所以我们在用scanf()输入数组变量时也可以不加‘&’,如下:[code_2]”
//[code_2]
#include
int main()
{
int a;
char str[20];
scanf("%d",&a);
scanf("%s",str);
return 0;
}
输出
“所以说,实际上scanf()与printf()在代码写法上的区别就是scanf()传入参数时,传入的是变量的地址,而printf()的参数直接传入变量就可以了。”
“在官方文档中还提供了scanf()很多其他的输入格式:”
官方文档:
“那么同学们,我们再来看下一个有趣的现象。为了清楚地说明这种现象我在代码中加入了输出函数[code_3]。”
#include
int main()
{
int a;
char str[20];
scanf("%d",&a);
printf("%d\n",a);
scanf("%s",str);
printf("%s\n",str);
return 0;
}
“当我们每输入一个变量就按下回车时会看到如下输出”,
输出1
“当我们每输入一个变量就按下空格时会看到如下输出”,
输出2
“你们有没有看出这两种不同的输入方式的输出有什么区别呢?”小刘发问到。
“第一种输出是被输入隔开的,第二种输出是一起的。”有的同学们小声的说到。
小刘点了点头道:“你们说的没错,但是为什么输入时敲下空格和回车的结果不同呢?换一种问法就是:输入完键入空格和回车有什么区别,这种区别是怎么产生的?”
所有人都沉默了。
小刘接着说:“那么我就给你讲讲这其中的奥秘。你们还记得我第一天给你们讲的“程序是怎么在计算机上运行的”这个程序流程图吗?”
黑板
“ 我们看图发现,在CPU和内存之间存在一个缓存,也可以叫缓冲区(Buffer)”
“ 那么这个缓冲区是干什么用的呢?我之前说过,CPU处理的数据是从内存中读取来的,但是CPU直接从内存读取数据的速度是非常非常慢的。那么为了提高cpu从内存的读取速度就在cpu和内存之间增设了一个缓冲区,缓冲区能同时保存大量数据,而cpu在缓冲区的读取速度相比于在内存上的读取速度简直就是火箭比牛车。所以内存就可以先把数据保存在缓冲区里,然后在由缓冲区向cpu传递,这样就能间接的传递数据并提高速率。因此在第二种用空格输入数据时没有立即获得输出的反馈是因为变量还在缓冲区中保存并没有传递给cpu进行处理,空格能区分两个变量但是不能中断数据的传入。但是如果你输入数据后键入的是回车,缓冲区就会接收到’\n’的信号,直接将所有变量值传递给cpu。这就是其中的奥秘所在。”
“原来如此!”所有人都大吃一惊,原来还有缓冲区在其中作祟。
小刘微微一笑道:“终于柳暗花明又一村了,掌握了printf()和scanf()在学其他其他的输入输出就都是皮毛,明天就给你们讲讲怎样调用C语言库函数输入输出字符串。”