c语言判断用户是否输入-非阻塞函数kbhit
一、基础研究
要从地址读取数据,肯定是要定义一个指针变量p,用它来实现变换地址和取值的功能。另外程序是当两个条件中的某一个出现时才停止,所以应该用while~do循环语句循环输出n和d,并用while进行判断。这里实现三个问题:
(1)循环地把值转换成地址。
(2)判断偏移地址是否为0xffff。
(3)判断用户是否输入了‘q’。
前两个问题比较好实现,对于第三个问题我们需要注意的是c语言是怎么处理用户输入的。之前做汇编课设的时候我们研究过汇编对于输入的处理,并且尝试过两个中断,一个是要中止等待用户输入的,一个是不中止等待的。现在我们的需求就类似于第二个中断,即等待用户输入同时不停止程序的运行。
首先写了一个程序如下:

编译时警告说0xffff在比较中超过常量范围,也就是超过int型的范围,将整个程序的int改成long后警告消失。int是两个字节,应该正好能够容纳偏移地址0xffff,为什么比较时会超出范围呢?难道是与比较的机制有关吗?这里作为一个问题来扩展研究。
将编译之后的程序进行连接,出现错误:getchar()函数没有定义,这说明在我们当前连接的obj文件里没有getchar()函数,解决的办法有两个:(1)用#include<stdio.h>导入头文件。(2)不使用getchar()函数。在这里我们先尝试第二种方法,scanf()函数会暂停程序等待输入,并且在输入完后还要按回车才能继续向下执行,所以不符合我们的需求。查找资料发现getche()函数不用敲回车就可以将字符输入,而getch()函数不用敲回车,也不显示,只是将字符输入进行处理。而且这两个函数也不需要导入其他文件,修改后的程序如下:

这时发现还有一个问题:每次循环都还要用户输入字符才能向下进行,就是说函数是阻塞的。在网上查找资料发现输入函数都是阻塞型的,那么我们可以调整思路,检测用户是否输入。查找资料发现输入检测函数有kbhit()函数,如果有输入它会返回一个非0值,没有就返回0,修改后的函数如下:

运行程序,它会不停地打印地址和地址的值,直到用户输入字符q。
但是运行结果发现:当地址为0xffff时,程序并没有停止:

将程序改成如下所示也不行:

这里可能是判断语句有问题,结果将判断语句改为p==(long *)0xffff之后程序在地址为0xffff时可以停止,修改的程序为:

之前是对数进行比较,修改后是对指针进行比较,那为什么对数进行比较会出错呢?我们觉得是因为将p强制类型转换成long会出错,再次修改程序如下:

发现虽然有警告,但是程序仍能正常执行,这说明用long型确实会对地址判断有影响。
二、扩展研究
(1)int是两个字节,应该正好能够容纳偏移地址0xffff,为什么比较时会警告超出范围呢?
答:因为int是带正负的类型,它的最高位为符号位,而0xffff是unsigned int类型,所以会超出范围。这里把它进行强制类型转换就行了。
(2)Getchar()的实现方式。
答:getchar 由宏实现:#define getchar() getc(stdin)。所以要与头文件相关联,它不是真正的函数,而是定义为预处理器宏。
(3)为什么用(long)p==0xffff判断时会识别不到0xffff,导致循环停不下来?
答:同样这里应该是unsigned long类型。
三、研究总结
c语言是接近底层的语言,这在它和汇编的联系上可以看出来。之前做课设时要用到非阻塞中断,在这里是用到非阻塞函数,问题是相似的,只不过实现的语言变了。但是只要我们掌握了程序设计的精髓,其他的就只是语法上的实现问题了。
还有,独立分析和思考的能力真的很重要,我们不要养成随便问问题的习惯,要先自己思考,抓住问题的本质,提出自己的猜想,然后在询问别人或者查资料去证实,这样自己解决问题的能力才能够得到成长。
c语言判断用户是否输入-非阻塞函数kbhit的更多相关文章
- 判断用户Input输入的事件来进行登陆
我们是通过键盘按的object.keyCode获取的 Html <input onkeydown="keydownMsg(event)" type="text&qu ...
- JS判断用户连续输入
方案1 // // $('#element').donetyping(callback[, timeout=1000]) // Fires callback when a user has finis ...
- Linux设备驱动中的阻塞和非阻塞I/O <转载>
Green 博客园 首页 新随笔 联系 订阅 管理 Linux设备驱动中的阻塞和非阻塞I/O [基本概念] 1.阻塞 阻塞操作是指在执行设备操作时,托不能获得资源,则挂起进程直到满足操作所需的条件 ...
- Linux设备驱动中的阻塞和非阻塞I/O
[基本概念] 1.阻塞 阻塞操作是指在执行设备操作时,托不能获得资源,则挂起进程直到满足操作所需的条件后再进行操作.被挂起的进程进入休眠状态(不占用cpu资源),从调度器的运行队列转移到等待队列,直到 ...
- 芯灵思Sinlinx A64开发板 Linux内核等待队列poll ---阻塞与非阻塞
开发平台 芯灵思Sinlinx A64 内存: 1GB 存储: 4GB 开发板详细参数 https://m.tb.cn/h.3wMaSKm 开发板交流群 641395230 阻塞:阻塞调用是指调用结果 ...
- 【转载】高性能IO设计 & Java NIO & 同步/异步 阻塞/非阻塞 Reactor/Proactor
开始准备看Java NIO的,这篇文章:http://xly1981.iteye.com/blog/1735862 里面提到了这篇文章 http://xmuzyq.iteye.com/blog/783 ...
- 非阻塞式socket的select()用法
Select在Socket编程中还是比较重要的,可是对于初学Socket的人来说都不太爱用Select写程序,他们只 是习惯写诸如 connect.accept.recv或recvfrom这样的阻塞程 ...
- IO之同步、异步、阻塞、非阻塞 (2)
[原创链接: http://www.smithfox.com/?e=191, 转载请保留此声明, 谢谢! ] I/O Model 是一个很大的话题, 也是一个实践性很强的事情, 网上有各种说法和资料, ...
- I/O模型(同步、非同步、阻塞、非阻塞)总结
I/O:同步(synchronous).异步(asynchronous).阻塞(blocking).非阻塞(nonblocking) 1.I/O内部机制 出于安全考虑,用户程序(用户态)是没办法直接操 ...
随机推荐
- windows 编程 —— 消息与参数(滚动条、键盘、鼠标)
目录: 滚动条 键盘 鼠标 滚动条ScrollBar 发送消息:WM_VSCROLL和WM_HSCROLL 参数wParam:wParam消息参数被分为一个低字组和一个高字组.wParam的低字组是一 ...
- Windows 10 TH2
Windows 10 TH2到底更新了啥? 15年11月,微软正式向Windows 10用户推送了Threshold 2(简称TH2)更新, 也就是传说中的November Update.更新后系统版 ...
- Java 编程的动态性,第 8 部分: 用代码生成取代反射--转载
既然您已经看到了如何使用 Javassist 和 BCEL 框架来进行 classworking (请参阅 本系列以前的一组文章), 我将展示一个实际的 classworking 应用程序.这个应用程 ...
- mysql 变量set
在游标循环中,使用使用select into 变量var时,再判断var isnull 或者length(var)=0时,跳出循环. 解决方式: 使用set var=(select id from t ...
- Android -- Messager与Service
如果你需要你的service和其他进程通信,那么你可以使用一个Messenger来提供这个接口. 这种方法允许你在不使用 AIDL的情况下,进行跨进程通信IPC. 实现步骤 下面是一个如何使用 Mes ...
- Android(java)学习笔记256:JNI之NDK的概念
1.交叉编译 (1)概念 在一个平台(硬件)和os(软件)环境下,编译出另一种平台和os下可以运行的二进制代码. e.g: 电脑端 ...
- 关于坑爹的PopupWindow的“阻塞”争议问题:Android没有真正的“阻塞式”对话框
请先允许我对网上某些没经过亲自实践人云亦云的同志呵呵... 那么开始正文,首先"阻塞"这个词本身就存在理解上的差异! 一般我们理解的阻塞,是阻塞了某个线程,即代码执行到这里后等待这 ...
- Mac搭建Git/GitHub全过程
在GitHub上注册了账号,建立了第一个hello-world repository,然后打算把Git平台配置在自己的机器上.因为是Mac OS,我也是一个初学者,很多功能需要自己摸索,于是各种百度, ...
- memcache和activemq使用连接,然后close
memcache和activemq使用连接,然后close
- Android 聊天气泡
网上搜到的只有一篇是自定义的TextView,其使用比较麻烦,所以采用大众化的方法--使用9.png来实现. 这里主要介绍sdk tool的draw9patch.bat的使用. 这个bat执行文件打开 ...