相信大家都对scanf这个函数并不陌生,但scanf到底是怎么实时监控键盘从而实现输入功能?不妨从0开始了解下这个其中的原理。
原理的概述
键盘的内部有一块微处理器,它控制着键盘的全部工作,比如主机加电时键盘的自检、扫描,扫描码的缓冲以及与主机的通讯等等。当一个键被按下时,微处理器便根据其位置,将字符信号转换成二进制码,传给主机和显示器。如果操作人员的输入速度很快或CPU正在进行其它的工作,就先将键入的内容送往内存中的键盘缓冲区,等CPU空闲时再从缓冲区中取出暂存的指令分析并执行。
1.键盘缓冲区
键盘缓冲区到底是什么?平时很多人说到scanf函数都会跟输入缓冲区扯上关系然后讨论一番,那么这里键盘缓冲区实质是什么?
键盘缓冲区的实质是在内存的一块区域
而且键盘缓冲区和输入缓冲区实际上是同一等级但不一定是同一个概念,因为键盘缓冲区是输入缓冲区一种,输入还可以是其他的设备,那么看到上面内容你可能会猜他为啥是在内存的一块区域?不急,请让我给你介绍一个东西——缓冲技术。
1.1 原理
是通过磁盘缓存来实现,磁盘缓存本身并不是一种实际存在的存储介质,它依托于固定磁盘,提供对主存储器存储空间的扩充。 主存可以看作是辅存的高速缓存, 因为辅存中的数据必须复制到主存方能使用;反之,数据也必须先存在主存中,才能最终输出到辅存。
1.2 缘由
为了缓和CPU和I/O设备速度不匹配的矛盾,提高CPU和I/O设备的并行性,在现代操作系统中,几乎所有的I/O设备在与处理机交换数据时都用了缓冲区,并提供获得和释放缓冲区的手段。总结来说,这个技术叫做缓冲区技术,用到了缓冲区,而缓冲区的引入是为了缓和CPU和I/O设备的不匹配,减少对CPU的中断频率,提高CPU和I/O设备的并行性。
1.3 实例
C++中清空键盘缓冲区或输入缓冲区就是指清空内存中存放键盘输入的那段空间
用cin、get、getline、getchar、gets等都能获取输入流的数据,另外,getch、getche等不能获取输入流的数据
如果无限制的输入,缓冲区就溢出了,溢出攻击就是这个原理了,把代码当成字符串写进缓冲区,等到它溢出,就可以进行攻击。
2.scanf函数
2.1 原理
int scanf(const char * restrict format,...);
函数 scanf() 是从标准输入流stdin(标准输入设备,一般指向键盘)中读内容的通用子程序(通用终端格式化输入函数),可以说明的格式读入多个字符,并保存在对应地址的变量中。
它从标准输入设备(不一定是键盘) 读取输入的信息。可以读入任何固有类型的数据并自动把数值变换成适当的机内格式。
其调用格式为: scanf("<格式化字符串>",<地址表>);
函数的第一个参数是格式字符串,它指定了输入的格式,并按照格式说明符解析输入对应位置的信息并存储于可变参数列表中对应的指针所指位置。每一个指针要求非空,并且与字符串中的格式符一一顺次对应。
2.2 缘由
scanf()函数执行成功时的返回值是成功读取的变量数,也就是说,你这个scanf()函数有几个变量,如果scanf()函数全部正常读取,它就返回几。
比如说:
函数返回值为int型。如果一个变量被成功读入,那么scanf的返回值就是1;
如果未被成功读入,返回值为0;
如果遇到错误或遇到end of file,返回值为EOF。end of file为Ctrl+z 或者Ctrl+d
2.3 实例
如果scanf中%d是连着写的如“%d%d%d”,在输入数据时,数据之间不可以用逗号分隔,只能用空白字符(空格或tab键或者回车键)分隔——“2 (空格)3(tab) 4” 或 “2(tab)3(回车)4”等。若是“%d,%d,%d”,则在输入数据时需要加“,”,如“2,3,4”。否则在你输入错误的格式之后会停在scanf函数前,不执行之后的语句。
以上就是关于scanf函数和键盘缓冲区的关系理解总结,希望能帮到学微机原理与接口技术的朋友们
|