C语言高级编程1.doc

上传人:豆**** 文档编号:17408107 上传时间:2022-05-23 格式:DOC 页数:44 大小:539.50KB
返回 下载 相关 举报
C语言高级编程1.doc_第1页
第1页 / 共44页
C语言高级编程1.doc_第2页
第2页 / 共44页
点击查看更多>>
资源描述

《C语言高级编程1.doc》由会员分享,可在线阅读,更多相关《C语言高级编程1.doc(44页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。

1、【精品文档】如有侵权,请联系网站删除,仅供学习与交流C语言高级编程1.精品文档.C语言高级编程技术8.1 递归程序设计8.1.1 递归与递归程序设计递归技术在算法和程序设计中是一种十分有用的技术,C语言提供了支持递归定义的机制和手段。递归有直接递归和间接递归两种。在一个函数的定义中出现了对自身的调用,称之为直接递归;一个函数f的定义中包含了对函数g的调用,而g的实现过程又调用了f,即函数调用形成了一个环状调用链, 这种方式称之为间接递归。页:236例8.1 编写一个递归函数,求n的阶乘值n!。若用fact(n)表示n的阶乘值,根据阶乘的数学定义可知:显然, 当n0时,fact(n)是建立在fa

2、ct(n-1)的基础上。由于求解fact(n-1)的过程与求解fact(n)的过程完全相同,只是具体实参不同,因而在进行程序设计时,不必再仔细考虑fact(n-1)的具体实现,只需借助递归机制进行自身调用即可。于是求n的阶乘值fact(n)的具体实现为:long fact(int n)long m;if (n = 0) return(1);elsem=n*fact(n-1);return(m);例8.2 编写一个递归函数,求Fibonacci数列第n项的值。若用Fibona(n)表示Fibonacci数列第n项的值,根据Fibonacci数列的计算公式:可知当n2 时,Fibonacci数列第

3、n项的值等于第n-1项的值与第n-2项的值相加之和,而Fibonacci数列第n-1项和第n-2项值的求解又分别取决于它们各自前两项之和。总之,Fibona(n-1)和Fibona(n-2)的求解过程与Fibona(n)的求解过程相同,只是具体实参不同。利用以上这种性质,我们在进行程序设计时便可以使用递归技术,Fibona(n-1)和Fibona(n-2)的求解只需调用函数Fibona自身加以实现即可。具体实现为:int Fibona(int n)int m;if (n=1 | n=2) return (1);elsem=Fibona(n-1)+ Fibona(n-2);return (m);

4、从上面两个实例可以看出,要使用递归技术进行程序设计,首先必须将要求解的问题分解成若干子问题,这些子问题的结构与原问题的结构相同,但规模较原问题小。由于子问题与原问题结构相同,因而它们的求解过程相同,在进行程序设计时,不必再仔细考虑子问题的求解,只需借助递归机制进行函数自身调用加以实现,然后利用所得到的子问题的解组合成原问题的解即可;而递归程序在执行过程中,通过不断修改参数进行自身调用,将子问题分解成更小的子问题进行求解,直到最终分解成的子问题可以直接求解为止。综上所述,递归程序设计具有以下两个特点:(1)具备递归出口。递归出口定义了递归的终止条件,当程序的执行使它得到满足时,递归执行过程便终止

5、。有些问题的递归程序可能存在几个递归出口;(2)在不满足递归出口的情况下,根据所求解问题的性质,将原问题分解成若干子问题,子问题的求解通过以一定的方式修改参数进行函数自身调用加以实现,然后将子问题的解组合成原问题的解。递归调用时,参数的修改最终必须保证递归出口得以满足。8.1.2 递归程序执行过程的分析递归程序的执行过程分为递推和回归两个阶段。在递推阶段,把较复杂的问题(规模为n)的求解推到比原问题简单一些的问题(规模小于n)的求解。例如例8.2中,求解Fibona(n),把它推到求解Fibona(n-1)和Fibona(n-2)。即是说,为计算Fibona(n),必须先计算Fibona(n-

6、1)和Fibona(n-2),而计算Fibona(n-1)和Fibona(n-2),又必须先计算Fibona(n-3)和Fibona(n-4)。依次类推,直至计算Fibona(1)和Fibona(2),分别能立即得到结果1和1。在递推阶段,必须要有终止递归的情况。例如在函数Fibona中,当n为1和2的情况。在回归阶段,当获得最简单情况的解后,逐级返回,依次得到稍复杂问题的解,例如得到Fibona(1)和Fibona(2)后,返回得到Fibona(3)的结果,在得到了Fibona(n-1)和Fibona(n-2)的结果后,返回得到Fibona(n)的结果。在编写递归函数时要注意,函数中的局部变

7、量和参数知识局限于当前调用层,当递推进入“简单问题”层时,原来层次上的参数和局部变量便被隐蔽起来。在一系列“简单问题”层,它们各有自己的参数和局部变量。由于递归引起一系列的函数调用,并且可能会有一系列的重复计算,递归算法的执行效率相对较低。当某个递归算法能较方便地转换成递推算法时,通常按递推算法编写程序。例如上例计算斐波那契数列的第n项的函数Fibona(n)应采用递推算法,即从斐波那契数列的前两项出发,逐次由前两项计算出下一项,直至计算出要求的第n项。由于递归调用是对函数自身的调用,在一次函数调用未结束之前又开始了另一次函数调用。这时为函数的运行所分配的空间在结束之前是不能回收的,必须保留。

8、这也意味着函数自身的每次不同调用,就需要分配不同的空间。只有当最后一次调用结束后,才释放最后一次调用所分配的空间,然后返回上一层调用,调用结束后,释放调用所分配的空间,再返回它的上一层调用,这样逐层返回,直至返回到第一次调用,当第一次调用结束后,释放调用所分配的空间,整个递归调用才完成。在例8.1中,给出了一个求阶乘的函数。下面以求4!为例,其调用过程如图8-1所示。要求4!,即要求的fact(4)值。图8-1 递归函数调用的执行过程8.1.3 递归算法的优缺点递归函数的主要优点是可以把算法写的比使用非递归函数时更清晰更简洁,而且某些问题,特别是与人工智能有关的问题,更适宜用递归方法。递归算法

9、的缺点,一是需要额外的内存开销,特别是当递归层次较大时,递归函数需要占用的堆栈空间相当大。二是递归引起一系列的函数调用,并且可能会有一系列的重复计算,递归算法的执行效率相对较低。总之,递归算法要比解决同样问题的非递归算法效率低一些。内存空间需求更多一些。大多数用递归算法解决的问题,都可以找到相应的非递归算法,只有少数问题的求解只有递归算法。由于递归算法具有效率低、内存消耗大等缺点,在设计程序时,若有比较好的非递归算法,应尽量采用非递归算法。8.1.4 递归程序设计的应用实例例8.3 编程实现将正整数转换为字符串。要求在主函数中输入正整数,转换以及输出编一递归函数完成。本例的关键在于设计一个递归

10、函数完成正整数n到字符串的转换,实现该函数的一个基本思想为:从高位到低位分别取出n的每一位上的数字,将它们转换成对应的字符后,按其原有的顺序输出;而在此转换过程中,将n前面的若干位(除个位外)对应的整数转换成字符串的过程与将整个整数转换成字符串的过程完全相同,只是处理的对象不同,因此可以通过递归调用实现,然后在此基础上再将n的个位数字转换成字符输出即可。显然,若n前面的若干位(除个位外)对应的整数为0时,递归调用应该终止。程序为:#include void convert(int n)int i,c;if (i=n/10)!=0) convert(i);c= n%10+ 0;putchar(c

11、);void main()int a;scanf(%d,&a);convert(a);例8.4 编程求两个正整数的最大公约数。要求编写一个递归函数求最大公约数。求最大公约数gcd(m,n)的求解公式为:由于以上最大公约数的定义本身即为递归定义,因此采用递归方式实现求m和n的最大公约数问题十分方便,将n=0作为递归的终止条件,其它情况只需按公式进行递归调用即可。程序为:#include int gcd(int m,int n)int k;if (n=0) return(m); else if (nm) return(gcd(n,m);elsek=m%n;return(gcd(n,k);void

12、main()int a,b;scanf(%d%d,&a,&b);printf(%d,gcd(a,b);例8.5 汉诺塔(Hanoi)问题。汉诺塔问题是一个著名的问题。约十九世纪末,在欧洲的商店中出售一种智力玩具,在一块铜板上有三根杆,最左边的杆上自上而下、由小到大顺序串着由64个圆盘构成的塔,游戏的目的是将最左边A杆上的圆盘,借助最右边的C杆,全部移到中间的B杆上,条件是一次仅能移动一个盘,且不允许大盘放在小盘的上面。如图8-2所示。图 8-2 汉诺塔由于问题中给出的圆盘移动条件是:一次仅能移动一个盘,且不允许大盘放在小盘的上面,这样64个盘子的移动次数是:18,446,744,073,709

13、,551,616。这是一个天文数字,若每一微秒可能计算(并不输出)一次移动,那么也需要几乎一百万年。我们仅能找出问题的解决方法并解决较小n值时的汉诺塔,但目前由于计算机的速度还不够快,尚不可能用计算机解决64层的汉诺塔。按照上面给出的方法分析问题,找出移动圆盘的递归算法。设要解决的汉诺塔共有n个圆盘,对A杆上的全部n个圆盘从小到大顺序编号,最小的圆盘为1号,次之为2号,依次类推,则最下面最大的圆盘的编号为n。第1步,先将问题简化。假设A杆上只有一个圆盘,即汉诺塔只有一层n=1,则只要将1号盘从A杆上移到B杆上即可。第2步,对于一个有n(n1)个圆盘的汉诺塔,将n个圆盘分为两部分:上面的n-1个

14、圆盘和最下面的n号圆盘。第3步,将上面的n-1个圆盘看成一个整体,为了解决n个圆盘的汉诺塔,可以按如下方式进行操作: A杆上面的n-1个盘子,借助B杆,移到C杆上(如图8-3所示);图8-3 A杆上剩下的n号盘子移到B杆上(如图8-4所示);图8-4整理上述分析结果,把第1步中化简问题的条件作为递归结束条件,将第3步分析得到的算法作为递归算法,可以写出如下完整的递归算法描述。定义一个函数movedisc(n,Aneedle,Bneedle,Cneedle)。该函数的功能是:将Aneedle杆上的n个圆盘,借助Cneedle杆,移动到Bneedle杆上。这样移动n个圆盘的递归算法描述如下:mov

15、edisc(n,Aneedle,Bneedle,Cneedle)if ( n=1 )将n号圆盘从Aneedle上移到Bneedle;else movedisc(n-1,Aneedle,Cneedle,Bneedle) 将n号圆盘从Aneedle上移到Bneedle; movedisc(n-1,Cneedle,Bneedle,Aneedle)按照上述算法可以编出如下程序。#include int i=0; /* 移动圆盘数量计数器 */void movedisc(unsigned int n, char Aneedle, char Bneedle, char Cneedle)if(n=1)pri

16、ntf(%2d-(%2d): %c = %cn,+i,n,Aneedle,Bneedle);/* 将Aneedle上的一个圆盘移到Bneedle上 */else movedisc(n-1, Aneedle, Cneedle, Bneedle);/* 将Aneedle上的n-1个圆盘借助Bneedle移到Cneedle上 */printf(%2d-(%2d): %c = %cn,+i,n,Aneedle,Bneedle);/* 将Aneedle上的一个圆盘移到Bneedle上 */movedisc(n-1,Cneedle,Bneedle,Aneedle);/* 将Cneedle上的n-1个圆盘借

17、助Aneedle移到Bneedle上 */void main( )unsigned n;printf(Please enter the number of discs:);scanf(%d,&n); /* 输入n值 */movedisc(n,a,b,c); /* 将A上的n个圆盘借助C将移动到B上 */printf(t Total: %dn, i);8.2 文本的屏幕输出和键盘输入8.2.1 文本的屏幕输出显示器的屏幕显示模式有两种:文本方式和图形方式。文本方式就是只能显示字符的方式,在文本模式下屏幕上可以显示的最小单位是字符。在文本模式下,坐标原点在屏幕左上角,其坐标为(1,1),X轴为水平

18、方向,Y轴为垂直方向。Turbo C 的字符屏幕函数主要包括文本窗口大小的设定、窗口颜色的设置、窗口文本的清除和输入输出等函数。这些函数的有关信息均包含在conio.h 头文件中,因此在用户程序中使用这些函数时,必须用include预处理命令将conio.h 包含进程序。1) 文本窗口的定义Turbo C 默认定义的文本窗口为整个屏幕,共有80 列25 行的文本单元。除了这种默认的80 列25 行的文本显示方式外,还可由用户通过textmode()函数来显式地设置Turbo C 支持的文本显示方式。Textmode()函数的函数原型为:void textmode(int newmode);该函

19、数将清除屏幕,以整个屏幕为当前窗口,并移光标到屏幕左上角。newmode 参数的取值见表8-1,既可以用表中指出的方式代码,又可以用符号常量。LASTMODE 方式指上一次设置的文本显示方式,它常用于在图形方式到文本方式的切换。方式符号常量显示列行数和颜色0BW404025黑白显示1C404025彩色显示2BW808025黑白显示3C808025彩色显示7MONO8025单色显示-1LASTMODE上一次的显示方式表8-1 Turbo C 支持的6种显示方式Turbo C 也允许用户根据自己的需要通过使用窗口设置函数window()重新设定显示窗口。window()函数的函数原型为:void

20、window(int left, int top, int right, int bottom);函数中形参(int left,int top)是窗口左上角的坐标,(int right,int bottom)是窗口的右下角坐标,其中(left,top)和(right,bottom)是相对于整个屏幕而言的。例如,要定义一个窗口左上角在屏幕(20,5)处,大小为30 列15 行的窗口可写成:window(20, 5, 50, 25);若window()函数中的坐标超过了屏幕坐标的界限,则窗口的定义就失去了意义,也就是说定义将不起作用,但程序编译连接时并不出错。窗口定义之后,用有关窗口的输入输出函数

21、就可以只在此窗口内进行操作而不超出窗口的边界。一个屏幕可以定义多个窗口,但现行窗口只能有一个(因为DOS 为单任务操作系统)。当需要用另一窗口时,可将定义该窗口的window()函数再调用一次, 此时该窗口便成为现行窗口了。2) 文本窗口颜色和其它属性的设置文本窗口颜色的设置包括背景颜色的设置和字符颜色(即前景色)的设置,使用的函数及其原型为:设置背景颜色函数:void textbackground(int color);设置字符颜色函数:void textcolor(int color);有关颜色的定义见表8-2。表中的符号常数与相应的数值等价,二者可以互换。例如设定蓝色背景可以使用text

22、background(1),也可以使用textbackground(BLUE),两者没有任何区别。符号常数数值含义背景或背景BLACK0黑前景、背景色BLUE1蓝前景、背景色GREEN2绿前景、背景色CYAN3青前景、背景色RED4红前景、背景色MAGENTA5洋红前景、背景色BROWN6棕前景、背景色LIGHTGRAY7淡灰前景、背景色DARKGRAY8深灰用于前景色LIGHTBLUE9淡蓝用于前景色LIGHTGREEN10淡绿用于前景色LIGHTCYAN11淡青用于前景色LIGHTRED12淡红用于前景色LIGHTMAGENTA13淡洋红用于前景色YELLOW14黄用于前景色WHITE15

23、白用于前景色BLINK128闪烁用于前景色表8-2 颜色表Turbo C 另外还提供了一个函数,可以同时设置文本的字符和背景颜色,这个函数是文本属性设置函数,其函数原型为:void textattr(int attr);参数attr 的值表示颜色形式编码的信息,每一位代表的含义如下:位76543210Bbbbcccc闪烁背景颜色字符颜色字节低四位cccc 设置字符颜色,46 三位bbb 设置背景颜色,第7位B 设置字符是否闪烁。假如要设置一个蓝底黄字,定义方法如下:textattr(YELLOW+(BLUE4);若再要求字符闪烁,定义变为:textattr(128+YELLOW+(BLUE4)

24、;注意:(1) 对于背景只有0到7共八种颜色,取大于7小于15 的数,则代表的颜色与减8后的值对应的颜色相同;(2) 用textbackground()和textcolor()函数设置了窗口的背景与字符颜色后,在没有用clrscr()函数清除窗口之前,颜色不会改变,直到使用了函数clrscr(),整个窗口和随后输出到窗口中的文本字符才会变成新颜色。(3) 用textattr()函数时背景颜色应左移4位,才能使3 位背景颜色移到正确位置。3) 窗口内文本的输入输出函数(1) 窗口内文本的输出函数前面介绍过的printf(),putc(),puts(),putchar()等输出函数以整个屏幕为窗口

25、的,它们不受由window 设置的窗口限制,也无法用函数控制它们输出的位置,但Turbo C 提供了三个文本输出函数,它们受窗口的控制,窗口内显示光标的位置,就是它开始输出的位置。当输出行右边超过窗口右边界时,自动移到窗口内的下一行开始输出,当输出到窗口底部边界时,窗口内的内容将自动产生上卷,直到完全输出完为止,这三个函数均受当前光标的控制,每输出一个字符光标后移一个字符位置。这三个输出函数原型为:int cprintf(char *format,表达式表);int cputs(char *str);int putch(int ch);它们的使用格式同printf(),puts()和putc(

26、),其中cprintf()是将按格式化串定义的字符串或数据输出到定义的窗口中,其输出格式串同printf 函数,不过它的输出受当前光标控制,且输出特点如上所述,cputs 同puts,是在定义的窗口中输出一个字符串,而putch()则是输出一个字符到窗口,它实际上是函数putc 的一个宏定义,即将输出定向到屏幕。(2) 窗口内文本的输入函数可直接使用stdio.h 中的getch()或getche()函数。需要说明的是,getche()函数从键盘上获得一个字,在屏幕上显示的时候,如果字符超过了窗口右边界,则会被自动转移到下一行的开始位置。4) 有关屏幕操作的函数void clrscr(void

27、);该函数将清除窗口中的文本,并将光标移到当前窗口的左上角处。void clreol(void);该函数将清除当前窗口中从光标位置开始到本行结尾的所有字符,但不改变光标原来的位置。void delline(void);该函数将删除光标所在行的所有字符。void gotoxy(int x, int y);该函数用于定位光标在当前窗口中的位置。这里x,y 是指光标要定位处的坐标(相对于窗口而言)。当x, y 超出了窗口的大小时,该函数不起作用。int movetext(int x1, int y1, int x2, int y2, int x3, int y3);该函数将把屏幕上左上角为(xl,y

28、1),右下角为(x2,y2)的矩形内文本拷贝到左上角为(x3,y3)的一个新矩形区内。这里x,y 坐标是以整个屏幕为窗口坐标系,即屏幕左上角为(1,1)。该函数与开设的窗口无关,且原矩形区文本不变。int gettext(int xl, int yl, int x2, int y2, void *buffer);该函数将把左上角为(xl,y1),右下角为(x2,y2)的屏幕矩形区内的文本存到由指针buffer指向的一个内存缓冲区内,当操作成功,返回1;否则,返回0。因一个在屏幕上显示的字符需占显示存储器VRAM 的两个字节,即第一个字节是该字符的ASCII 码,第二个字节为属性字节,即表示其显

29、示的前景、背景色及是否闪烁,所以buffer 指向的内存缓冲区的字节总数的计算为:字节总数=矩形内行数每行列数2其中:矩形内行数=y2-y1+l,每行列数=x2-xl+1(每行列数是指矩形内每行的列数)。矩形内文本字符在缓冲区内存放的次序是从左到右,从上到下,每个字符占连续两个字节并依次存放。int puttext(int x1, int y1, int x2, int y2, void *buffer);该函数则是将gettext()函数存入内存buffer 中的文字内容拷贝到屏幕上指定的位置。注意:(1) gettext()函数和puttext()函数中的坐标是对整个屏幕而言的,即是屏幕的

30、绝对坐标,而不是相对窗口的坐标;(2) movetext()函数是拷贝而不是移动窗口区域内容,即使用该函数后,原位置区域的文本内容仍然存在。例8.6:下面的程序首先定义了一个字符数组,下标为64,表示用来存四行八列的文本。由于没有用window 函数设置窗口,因而用缺省值,即全屏幕为一个窗口,程序开始设置80列25 行文本显示方式(C80),背景色为蓝色,前景色为红色,经clrscr 函数清屏后,设置的背景色才使屏幕背景变蓝。gotoxy(10,10)使光标移到第10 行10 列,然后在(10,10)开始位置显示L:load,接着在下面三行相同的列位置显示另外三条信息,13 行10 列显示的E

31、:exit 后面带有回车换行符,为的是将光标移到下一行开始处,好显示press any key to continue。当按任一键后,gettext 函数将(10,l0,18,13)矩形区的内容存到ch 缓存区内。ch 即上述的四行八列信息,接着设置一个窗口,并纵向写上1,2,3,4,然后用movetext(),将此窗口内容复制到另一区域,由于此区域包括背景色和显示的字符,所以被复制到另一区域的内容也是相同的背景色和文本。当按任一键后,又出现提示信息,再按键,则存在ch缓冲区内的文本由puttext()又复制到开设的窗口内了,注意上述的函数movetext(),gettext(),puttex

32、t()均与开设的窗口内坐标无关,而是以整个屏幕为参考系的。#include #include void main()int i;char ch4*8*2; /* 定义ch 字符串数组作为缓存区*/textmode(C80);textbackground(BLUE);textcolor(RED);clrscr();gotoxy(10,10);cprintf(L:load);gotoxy(10,11);cprintf(S:save);gotoxy(10,12);cprintf(D:delete);gotoxy(10,13);cprintf(E:exitrn);cprintf(Press any k

33、ey to continue);getch();gettext(10,10,18,13,ch); /* 存矩形区文存到ch 缓存区*/clrscr();textbackground(1);textcolor(3);window(20,9,34,14); /* 开一个窗口*/clrscr();cprintf(1.rn2.rn3.rn4.rn);/* 纵向写1,2,3,4 */movetext(20,9,34,14,40,10); /* 将矩形区文本复制到另一区域*/puts(hit any key);getch();clrscr();cprintf(press any key to put te

34、xt);getch();clrscr();puttext(23,10,31,13,ch); /* 将ch 缓存区所存文本在屏上显示*/getch();5)状态查询函数有时需要知道当前屏幕的显示方式,当前窗口的坐标、当前光标的位置,文本的显示属性等,Turbo C 提供了一些函数得到屏幕文本显示有关信息的函数:void gettextinfo(struct text_info *f);这里的text_info 是在conio.h 头文件中定义的一个结构,该结构的定义是struct text_infounsigned char winleft; /* 窗口左上角x 坐标*/unsigned cha

35、r wintop; /* 窗口左上角y 坐标*/unsigned char winright; /* 窗口右下角x 坐标*/unsigned char winbottom; /* 窗口右下角y 坐标*/unsigned char attributes; /* 文本属性*/unsigned char normattr; /* 通常属性*/unsigned char currmode; /* 当前文本方式*/unsigned char screenheight; /* 屏高*/unsigned char screenwidth; /* 屏宽*/unsigned char curx; /* 当前光标

36、的x 值*/unsigned char cury; /* 当前光标的y 值*/例8.7 下面的程序将屏幕设置成80列彩色文本方式,并开了一个window(1,5,70,20)的窗口,在窗口中显示了current information of window,然后用gettextinfo 函数得到当前窗口的信息,后面的cprintf()函数将分别显示出结构text_info 各分量的数值来。#include #include void main()struct text_info current;textmode(C80);textbackground(1);textcolor(13);windo

37、w(1,5,70,20);clrscr();cputs(Current information of windowrn);gettextinfo(¤t);cprintf(Left corner of window is %d,%d ,current.winleft,current.wintop);cprintf(Right corner of window is %d,%d ,current.winright,current.winbottom);cprintf(Text window attribute is%d ,current.attribute);cprintf(Text

38、window normal attribute is %d ,current.normattr);cprintf(Current video mode is %d ,current.currmode);cprintf(Window height and width is %d,%d ,current.screenheight,current.screenwidth);cprintf(Row cursor pos is %d,Column pos is %d ,current.cury,current.curx);getch();8.2.2 键盘输入当我们在键盘上按下某键时,系统是怎样知道是哪一

39、个键被按下呢?它的奥妙在于计算机键盘内有一个微处理器,它用来扫描和检测每个键的按下和拾起状态。然后以程序中断的方式(INT 9)与主机通信。ROM 中BIOS 内的键盘中断处理程序,会将一个字节的按键扫描码(扫描码的06 位标识了每个键在键盘上的位置,最高位标识按键的状态,0 对应该键是被按下;1 对应松开。它并不能区别大小写字母,而且一些特殊键如PrintScreen 等不产生扫描码直接引起中断调用)翻译成对应的ASCII 码。由于ASCII 码仅有256 个,它不能将PC 键盘上的键全部包括,因此有些控制键如CTRL,ALT,END,HOME,DEL 等用扩充的ASCII 码表示,扩充码用

40、两个字节的数表示。第一个字节是0,第二个字节是0255 的数,键盘中断处理程序将把转换后的扩充码存放在Ax 寄存器中,存放格式如表8-3 所示。对字符键,其扩充码就是其ASCII 码。键名AHAL字符键扩充码=ASCII 码ASCII 码功能键/组合键扩充码0表8-3 键盘扫描码是否有键按下,何键按下,简单的应用中可采用两种办法:一是直接使用Turbo C 提供的键盘操作函数bioskey()来识别,二是通过int86()函数,调用BIOS的INT 16H,功能号为0 的中断。它将按键的扫描码存放在Ax 寄存器的高字节中。函数bioskey()的原型为:int bioskey(int cmd)

41、;它在bios.h 头文件中进行了说明,参数cmd 用来确定bioskey()如何操作,其含义见表8-4。cmd操作0bioskey()返回按健的键值,该值是2 个字节的整型数。若没有键按下,则该函数一直等待,直到有键按下。当按下时,若返回值的低8 位为非零,则表示为普通键,其值代表该键的ASCII 码。若返回值的低8 位为0,则高8 位表示为扩展的ASCII码,表示按下的是特殊功能键。1bioskey()查询是否有键按下。若返回非0 值,则表示有键按下,若为0 表示没键按下。2bioskey()将返回一些控制键是否被按过,按过的状态由该函数返回的低8 位的各位值来表示:字节位对应的16 进制

42、数含义00x01右边的shift 键被按下10x02左边的shift 键被按下20x04Ctrl键被按下30x08Alt 键被按下40x10Scroll Lock 已打开50x20Num Lock 已打开60x40Caps Lock 已打开70x80Insert 已打开表8-4 函数bioskey(int cmd)中 cmd的取值及含义当某位为l 时,表示相应的键已按,或相应的控制功能已有效,如选参数cmd 为2,若key 值为0x09,则表示右边的shift 键被按,同时又按了Alt 键。函数int86 ()的原型为:int int86(int intr_num,union REGS *in

43、regs,union REGS *outregs);这个函数在bios.h 头文件中进行了说明,它的第一个参数intr_num 表示BIOS 调用类型号,相当于int n 调用的中断类型号n,第二个参数表示是指向联合类型REGS 的指针,它用于接收调用的功能号及其它一些指定的入口参数,以便传给相应的寄存器,第三个参数也是一个指向联合类型REGS 的指针,它用于接收功能调用后的返回值,即出口参数,如调用的结果,状态信息,这些值从相关寄存器中得到。例8.8 bioskey()函数的使用。#include #include void main() int k1,k2,k; do k=bioskey(

44、0); k1=k & 0x00FF; /*得到低8位的值*/ k2=k 8; /*得到高8位的值*/ switch(k2) case 71: printf(你按下了Home键!n); break; case 79: printf(你按下了End键!n); break; case 73: printf(你按下了PgUp键!n); break; case 81: printf(你按下了PgDn键!n); break; default: printf(你按下了Home,End,PgUp,PgDn之外的键!n); while(k1!=27);/*ESC键才退出*/8.3 图形程序设计计算机图形程序设计

45、是程序设计中比较难,但又吸引人的部分。因在ANSI C中没有对图形库的要求,所以不同版本的C语言编译程序提供的图形函数不一样。本节以Turbo C的图形库来介绍图形程序设计。8.3.1 图形模式的初始化要进行图形程序设计,就要将屏幕显示模式设置为图形模式。要设置图形模式,可以用Turbo C提供的图形初始化函数: void far initgraph(int far *gdriver,int far *gmode,char far *pathtodriver);其中,gdriver表示图形驱动器,gmode表示图形模式,pathtodriver表示图形驱动程序所在的目录路径,若图形驱动程序在Turbo C的默认目录下,可将参数pathtodriver设置为空字符串( )。若不知道所用的图形显示器适配器的种类,在调用图形初始化函数时,设置参数gdriver的值为0或D

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 教育专区 > 小学资料

本站为文档C TO C交易模式,本站只提供存储空间、用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。本站仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知淘文阁网,我们立即给予删除!客服QQ:136780468 微信:18945177775 电话:18904686070

工信部备案号:黑ICP备15003705号© 2020-2023 www.taowenge.com 淘文阁