背景:                 
[本书目录] [图书首页] [本书讨论区]  
链接地址:http://www.17xie.com/read-6167.html    注册17xie 一起来写书 实现您的出书梦想!

[9-10]  写出下面程序的运行结果。

'EXAMPLE 10

a=100

b=50

FOR i=1 TO 2

p=i MOD2+1

ON p GOSUB add,subtract

NEXT i

PRINT

END

add:PRINT a+b;

RETURN

subtract:PRINTa-b;

RETURN

程序的运行结果为:

150          50

本题中的主程序是一个FOR循环,共循环两次,子程序1和子程序2的标号分别为addsubtract,给定的条件是p=i MOD 2+1,在循环执行过程中,P依次被赋值为12,在执行ON GOSUB语句时,分别执行add tsubtract这两个子程序,先后打印输出15050

3ON KEYnGOSUBRETURN语句

当用户需要在程序运行的过程中,通过键盘来干预程序的执行,让计算机完成一个特定的操作时,可以使用ON KEYnGOSUB〈子程序入口〉

功能:在程序中指定一个键,设置事件陷阱。

说明:

1)格式的n是一个数值表达式,代表一个键。n的值设定的键的对应关系见表9-1所示。

9-1  KDYn)中n与键的对应关系

n的值

  

1~10

功能键F1~10

11

方向键↑

12

方向键←

13

方向键→

14

方向键↓

2ON KEYnGOSUB语句的作用是:在程序中指定一个键,如果在程序执行过程中用户按下该键,程序就会中断原来的操作过程,转而执行事先设置的一个子程序,执行完这个子程序后再返回原来的主程序继续执行。这种功能称为“事件捕捉”,按一个特定的键就是一个“事件”。“捕捉”到此“事件”就转子程序处理。“事件捕捉”功能又称“陷阱”。这样的子程序称“事件捕捉子程序”或“陷阱子程序”。

[9-11]  编写一个程序,在程序开始运行后,只要按一次F5键,屏幕上就显示当时的时间。

程序如下:

'EXAMPLE 11

ON KEYnGOSUB t

KEY(5) ON

DO

LOOP UNTIL INKEY$<>""

END

KEY(3)OFF

t:PRINT"时间:"TIME$

RETURN

程序中第一行设n值为5,也就是指定键盘上的功能键F5为“陷阱键”。在程序运行过程中任何时候按下F5键,就转去执行陷阱子程序。该子程序输出当前时间,每按一次F5键,显示一次。程序第4行的作用的等待键盘上的一个操作,如键盘上无任何输入,循环不断运行,如要程序终止,则可按下F5键以外的任何键。

程序运行结果如下(按3F5键):

时间:202056

时间:202103

时间:202112

按回车键后程序结束。

9.3.2  SUB子程序

1.定义子程序过程语句SUBEND SUB

Quick BASIC中用SUB语句定义子程序过程。

格式:

SUB〈过程名〉[(〈参数表〉)][STATIC

[〈语句块〉]

END SUB

功能:定义一个SUB子过程。

说明:

1)〈过程名〉即子程序过程的名字,是一个不超过40个字符的字符串,不能有数据类型后缀。一个程序只能有一个惟一的过程名。

2)〈参数表〉是主程序调用本过程时传送给本过程的一个或多个简单变量名、数组名,各变量名之间用逗号分隔。〈参数表〉指明了传送给过程的变量个数和类型,其格式为:

〈变量1〉[()][AS〈类型〉][,〈变量2〉[()][AS〈类型〉]]…

这里的〈变量〉是一个Quick BASIC变量名,如果是数组变量,要在数组名后面加上一对小括号。

〈类型〉是对应〈变量〉的数据类型,可以是INTEGERLONGSINGLEDOUBLESTRING或用户定义数据类型。

〈参数表〉中的参数是形式参数,不能用定长字符串变量或定长字符串数组作为形式参数。不过可以在CALL语句中用简单定长字符串变量作为形式参数,在调用SUB过程之前,Quick BASIC把它转换为变长字符串变量。

3STATIC定义过程中局部变量在内存中的存储方式。如果使用STATIC属性,则过程中的局部变量是STATIC(静态)的,即在每次调用过程时,各局部变量的值保持不变;如果省略STATIC,则局部变量主默认为自动的,即在每次调用过程时,局部变量初始化为0或空字符串。

4SUB过程以SUB开始,以END SUB结束。当程序遇到END SUB时,将退出过程并立即返回到调用语句的下面语句。

5)〈语句块〉是Quick BASIC的程序段,语句块中可以用一个或多个EXIT SIB语句从过程中退出。

6)在过程定义中不能使用SUBEND SUBFUNCTIONEND FUNCTION DEF FNEND DEFCOMMONDECLAREDIM SHAREDOPTION BASETYPEEND TYPE语句。

SUB过程中不能定义SUB过程、FUNCTION过程、DEF FN函数。即在过程内不能嵌套过程定义或DEF FN函数,但是一个过程可以调用另一个过程或DEF FN函数。

2.调用子程序过程语句CALL

要执行一个过程,必须调用该过程,SUB过程调用可以作为独立的基本语句。调用SUB过程的方式有两种:一种是把过程名放在一个CALL语句中;另一种是把过程名本身作为一个语句来使用。

格式:

CALL]〈过程名〉[(〈变元表〉)]

功能:把控制传送到SUB过程。

说明:

1)〈过程名〉是需调用的SUB过程名。

2)〈变元表〉是传送给SUB过程的变量或常量,各变元之间用逗号分隔。用数组名后跟空括号指定数组参数。

3)如果省略CALL关键字,也要同时去掉包括变元表的小括号,这时要在调用前用DECLARE语句说明。如果在Quick BASIC环境中保存它,Quick BASIC将自动产生DECLARE语句。

下面是两种调用方式的区别:

DECLARE SUB proce(first%,second$)           '说明过程语句

CALL proce(first%,second$)                   'CALL调用时的语句

proce first%,second$                         '省略CALL时的调用语句

[9-12]  SUB子程序计算4+5+6!的值。

问题分析:要计算s=4!+5!+6!,先要分别计算出4!,5!和6!。由于3个求阶乘的运算过程完全相同,因此可以用子程序来计算任意阶乘m!,每次调用子程序前给m一个值,在子程序中其所求结果放入total变量中,返回主程序后tot变量接收total的值。这样3次调用子程序便可求得s

主程序为:

'EXAMPLE 12

DECLARE SUB fact(m!,total!)

CLS

a=4:b=5:c=6

CALL fact(a,tot)

s=tot

CALL fact(b,tot)

s=s+tot

PRINT a;"!+";b;"!+";c;"!=";s

END

子程序为:

SUB fact(m,total)                '计算阶乘子程序

total=1

FOR i=1 TO m

total=total*i

NEXT i

END SUB

程序运行结果为:

4+5+6!=864

9.3.3  说明过程语句DECLARE

Quick BASIC中,定义的过程要在主程序中用说明过程语句DECLARE说明。

格式:

DECLARE{FUNCTIONSUB}〈过程名〉[([〈参数表〉])]

功能:说明被调用的一个FUNCTIONASUB过程名,并且检查各参数的数据类型。

说明:

1)〈过程名〉是程序中的FUNCTIONSUB过程名。

2)〈参数表〉是主程序调用过程时给传送给过程的一个或多个变量,其格式为:

〈变量1〉[()][AS〈类型〉][,〈变量2〉[()][AS〈类型〉]]…

〈变量〉是一个Quick BASIC变量名。

〈类型〉是对应〈变量〉的数据类型,可以是INTEGERLONGSINGLEDOUBLESTRING或用户定义数据类型。即任何允许的数据类型。

3DECLARE语句中的参数表主要是对传送过程的变元进行类型检查。

4DECLARE语句必须和在主程序中第一个可执行语句之前。作为约定DECLARE语句出现在程序注释语句之后,常数及变量说明符之前。

5)在主程序中,如果省略DECLARE语句,在Quick BASIC编辑环境中,当把程序存盘时,将自动在主程序的开始入加入属于本过程的DECLARE语句。

由于DECLARE语句会在Quick BASIC的编辑环境中自动产生,所以用户不用专门输入。

但是,维护参数表的工作仍要由用户自己完成,如果修改子程序中的参数表,也必须修改DECLARE语句中的参数表,使之相互匹配。

9.4  调用过程时的数据传递

调用过程时可以把数传递给过程,也可以把过程中的数据传递回来。在调用过程中,要考虑调用程序和被调用程序之间的数据是如何传递的。通常在编制一个子程序时,要考虑它需要输入哪些量,进行处理后输出哪些量。正确地提供一个子程序的输入数据和正确地引用其输出数据,是使用子程序的关键问题,也就是调用程序和被调用程序之间的数据传递。

在调用一个过程时必须完成形式参数与实际参数的结合,即把实际参数传送给形式参数,然后实际参数执行调用的过程。在Quick BASIC中,通常把形式参数叫做参数,把实际参数叫做变元。

9.4.1  参数与变元

变元(实际参数)是在调用SUBFUNCTION过程时传送给SUBFUNCTION过程的常量、变量或表达式。参数(形式参数)是出现在SUBFUNCTIONDECLARE语句中的变量名是接收传送给子程序值的变量。

参数与变元的对应关系为:

实际参数

调用过程:CALL testsub(    a%,b!,"Test" 16.8)

定义过程:SUB  testsub(    r%,s!,   t$,      x)STATIC

                                    形式参数

在定义过程中,形式参数为实际参数保留位置,当调用过程时,实际参数被插入形式参数中各变量处,第一个形式参数接收第一个实际参数的值,第二个形式参数接收第二个实际参数的值,…。

实参表和形参表中对应的变量名不必相同,但是变量的个数必须相等,并且对应变量的类型必须相同。

1.形参表

形参表中的各个变量之间用逗号分隔,表中的变量是:

1)后面跟有左、右圆括号的数组名:若括号内有数字,一般表示数组的维数。

2)除定长字符串之外的合法变量名。即在形参表中只能用如x$x AS STRING之类的变长字符串作为形式参数,不能用如x AS STRING*10之类的定长字符串作为形式参数。但定长字符串可以作为实际参数传递给过程。

2.实参表

实参表可由常量、表达式、有效的变量名、数组名(后跟左、右括号)组成,变元表中各变元用逗号分隔。例如,下面是具有参数表的一个子程序定义的语句行:

SUBtestsub(i%,aa(),re AS rectype,cc$)

其中:i%是整型参数、aa是一个单精度数组、rerectype类型的记录、cc$是一个字符串。

用下面的程序调用过程testsub,并把4个变元传送给相应的参数。

TYPE rectype              '定义用户类型

xm AS STRING*12

dz AS LONG

END TYPE

DIM re AS rectype         '定义一个rectypt类型的变量re

CALL testsub(i%,cj(),re,"Kaifeng")

3.传址调用和传值调用

传递参数的方式有两种。如果CALL语句中的变元(实际参数)为变量,就是传址调用;如果CALL语句中的变元(实际参数)是常量或表达式,就是传值调用。

9.4.2  传址调用

传址调用或称按地址传递,是指形式参数与实际参数使用相同的内存地址单元。所以,如果形式参数发生变化,实际参数也随着改变。在传址调用时,实际参数必须是变量,绝不能是常量或表达式。

传址调用会把过程的执行结果带回调用的程序,因此,在返回程序时实际参数的内容可能已经发生了变化。

[9-13]  阅读下面的程序,分析输出结果,理解传址调用。

主程序为:

'EXAMPLE 13

DECLARE SUB prod(x!,y!,z!)

CLS

a=5:b=3

PRINT "主程序调用前的变量值a,b,c",a,b,c

END

子程序为:

SUB prod(x!,y!,z!)

PRINT"子程序运算前的变量值x,y,z",x,y,z

z=x*y

PRINT"子程序中运算后的变量值x,y,z",x,y,z

END SUB

程序的运行结果为

主程序调用前的变量值a,b,c                 5       3       0

子程序中运算前的变量值x,y,z            5       3       0

子程序运算后的变量值x,y,z                5       3       15

主程序调用后的变量值a,b,c                 5       3       15

主程序CALL语句中的变量abc与子程序中相对应的变量xyz使用相同的内存

字数:7175    最后更新:1年以前 [08-16 19:45]我爱钱 修改
本页编辑者:我爱钱  
[前一页]:第九章  [后一页]:第九章
[在本页中加入书签] [收藏本书] [推荐本书]
  17xie论坛 > 本书讨论区 > 本页评论   (共0条)
发表评论

用户名称 匿名发表
评论内容
验证码

关于我们 | 版权声明 | 免责声明 | 诚聘英才 | 联系我们 | 合作伙伴 | 友情链接 | 广告合作 | 提交意见
Copyright © 2007 17xie.com 互联网协同写书平台 京ICP备08002671号