4.7 特殊的程序流程 – 事件驱动
程序员经常用事件驱动的方式编写那些工作在GUI(Graphical User Interface,图形用户界面)环境中的应用程序,例如,Windows操作系统中的应用程序。这听起来好像挺复杂的,但其实如果把事件驱动想象成两个程序在对话,理解起来就简单了
下面看一个实际的例子。代码清单4.5中列出了一段用C语言编写的Windows应用程序,这里只列出了程序的骨架。在程序中有WinMain()和WndProc()两个函数(代码块)。WinMain()是在程序启动时被调用的主例程(Main Routine)。而WndProc()并不会被诸位所编写的程序本身调用,Windows操作系统才是WndProc()的调用者。这种机制就使得Windows和诸位所编写的应用程序之间进行对话
代码清单4.5 用C语言编写的Windows应用程序的骨架
/*主例程*/
int APIENTRY WinMain(HINSTANCE hInst, HINSTANCE hPrevInst,LPSTR lpCmdLine, int nCmdShow){
…
}
/*窗口过程*/
LRESULT CALLBACK WndProc(HWND hWnd, UNIT msg, WPARAM wParam, LPARAM lParam){
…
}
通常把用户在应用程序中点击鼠标键或敲击键盘按键这样的操作称为事件(Event)。负责检测事件的是Windows。Windows通过调用应用程序的WndProc()函数通知应用程序事件的发生。而应用程序则根据事件的类型做出相应的处理。这种机制就是事件驱动。可以说事件驱动也是一种特殊的条件分支,它以从Windows送来的通知为条件,根据通知的内容决定程序下一步的流程
要实现事件驱动,就必须把应用程序中的WndProc()函数(称为窗口过程,Window Procedure)的起始内存地址告诉Windows。这一步将在应用程序WinMain()中作为初始化处理被执行
事件驱动是一种适用于GUI环境的编程风格。在这种环境中用户可以通过鼠标和键盘来操作应用程序。虽然事件驱动的程序也可以用流程图表示,但由于要排列很多的菱形符号(表示条件分支),画起来会很复杂。所以下面介绍便于表示事件驱动的“状态转化图”。状态转化图中有多个状态,反映了由于某种原因从某个状态转化到另一个状态的流程。工作在GUI环境中的程序,其显示的在画面上的窗口就有若干个状态。例如,图4.15所示的计算器应用程序就可以看作包含三个状态:“显示计算机结构”、“显示第一个输入的数”以及“显示第二个输入的数”。随着用户按下不同种类的键,状态也会发生转变。
图4.15 Windows附带的计算器应用程序
在状态转化较中,用矩形写上状态的名称,用箭头表示状态转化的方向,并且在箭头上标注引起状态转化的原因(事件)(如图4.16所示)
图4.16 计算器应用程序的状态转化图
对于觉得画图很麻烦的人,笔者推荐使用“状态转化表”(如表4.2所示)。因为制表的话,用Excel等表格软件就可以完成,修改起来也要比图方便。在状态转化表中,行标题是带有编号的状态,列标题是状态转化的原因,而单元要是目标状态的编号
表4.2 计算机程序的状态转化表的例子
也许读完中断处理和事件驱动这两节,诸位会觉得稍微有些混乱,但程序的流程还是只有顺序执行、条件分支和循环三种。这一点没有改变,其中的顺序执行是最基本的程序流程,这是因为CPU中的PC寄存器的值会自动更新,条件分支和循环,在高级语言中用程序块表示,在机器语言和汇编语言中用跳转指令表示,在硬件上是通过把PC寄存器的值设为要跳转到的目的地的内存地址来实现的。只要能充分理解这些概念就OK了
在接下来的第5章,将更详细地介绍在本章略有涉及的算法
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论