在Quick BASIC中DEF函数的使用规则如下:
(1)先定义后调用。如果程序中要使用自定义函数,那么必须在调用之前进行定义,否则,将会出现“Function not defined”(函数未定义)的错误信息。因此,习惯上都把DEF fn语句放在程序或者程序段的开头。
(2)定义自定义函数的时候,〈函数表达式〉中的自变量只是一个“形式参数”(或者称“虚拟参数”),它并不是一个实际存在的变量。因此它使用什么名字对自定义函数本身并不产生影响,也可以和程序中的变量同名,但它们并不代表同一对象。
(3)调用自定义函数的时候,必须以“实际参数”(一个确定的值)代替“形式参数”,这个过程叫“虚实结合”,实际参数必须与形式参数的个数相同。“实际参数”简称“实参”,“形式参数”简称“形参”。
(4)函数可以嵌套定义,也就是定义一个函数时,此函数内可以出另一个已经定义了的函数;函数可以嵌套调用,也就是一次调用函数时,实参可以是另一次调用的结果。
(5)使用多行DEF函数的进修,要注意DEF fn和END DEF必须配套使用;格式中必须有“fn〈函数名〉=〈表达式〉”语句给自定义函数赋值。
FUMCTION函数也叫模块化函数或者是函数过程。它不像DEF函数是设置在某一个程序模块之中的,而是可以作为独立的模块使用。
格式:
FUNCTION〈过程名〉[(〈参数表〉)][STATIC]
[〈语句块1〉]
〈过程名〉=〈表达式〉
[〈语句块2〉]
END FUNCTION
功能:定义一个FUNCTION函数过程,可以是一个独立模块。
说明:
(1)〈过程名〉即函数过程的名字,并且用指定的数据类型后缀返回它的数据类型,数据类型后缀为%、&、!、#或$。
(2)〈参数表〉中的参数是形式参数,不能用定长字符串变量或定长字符串数组作为形式参数。
(3)STATIC定义过程中局部变量在内存中的存储方式。如果使用STATIC属性,则过程中的局部变量是STATIC(静态)的,即在每次调用过程时,各局部变量初始化为0或空字符串。
(4)〈表达式〉的值是函数返回的结果。调用FUNCTION过程要返回一个值,因此可以像内部函数一样在表达式中使用。FUNCTION过程返回一个值,放在格式中的〈表达式〉中,并通过语句〈表达式〉语句,则该过程返回一个默认值,数值函数过程返回0,字符串函数过程返回字符串。因此,为了能使一个FUNCTION过程完成所指定的操作,通常要在过程中为过程名赋值。
(5)〈语句块〉是Quick BASIC的程序段,语句块中可以用一个或多个EXIT FUNCTION语句从函数中退出。
由于FUNCTION过程返回一个值,在调用时完全可以像使用Quick BASIC内部函数一样对待,只不过内部函数由软件公司提供,而FUNCTION过程由用户自己定义。
调用FUNCTION过程很简单,像使用内部函数一样,把它写在表达式中就可以了。
[例9-6] 求1~6的立方数。
主程序为:
'EXAMPLE 6
DECLARE FUNCTION cube!(v!)
FOR x=1 TO 6
PRINT x,cube(x)
NEXT x
END
定义计算立方数的FUNCTION函数:
FUNCTION cube(v) '计算立方函数
vt=v*v*v
cube=vt
END FUNCTION
程序运行后输出结果为
1 1
2 8
3 27
4 64
5 125
6 216
[例9-7] 定义随机整数函数,产生30个1~100之内的随机数。
主程序为:
'EXAMPLE 7
DECLARE FUNCTION randomnum%()
FOR r=1 TO 30
PRINT randomnum% '输出产生的随机整数
NEXT r
END
定义随机整数函数:
FUNCTION randomnum% '定义随机整数函数
RANDOMIZE TIMER
randomnum%=(RND*100+1)\1
END FUNCTION
[例9-8] 任意输入两个数,输出这两个数中的最大数。
主程序为:
'EXAMPLE 8
DECLARE FUNCTION max!(x!,y!)
INPUT "请输入两数:";a,b
PRINT "这两个数中的最大数是:";max(a,b)
END
定义求两个数中的最大数函数:
FUNCTION max(x,y) '定义求两数最大数函数
IF x>y THEN
max=x
ELSE
max=y
END IF
END FUNCTION
程序运行结果为:
请输入两个数:?2,3
这两个数中的最大数是:3
请输入两个数:?60,39
这两个数中的最大数是:60
请输入两个数:?44,80
这两个数中的最大数是:80
实现模块化的主要手段是自定义函数和子程序。但是无论是单行和多行DEF函数,还是FUNCTION函数过程,它们的共同点都是返回函数值。但是,有时需要重复的运算只是一个过程,这时就可以采用子程序。
在程序设计中,通常将重复使用的程序,设计成能够完成一定功能的可供其他程序使用(调用)的相对独立的程序段,这种程序段一般称为子程序。它独立存在,但可以被多次调用,调用的程序称为主程序。
Quick BASIC语言中有两种形式的子程序,即GOSUB子程序和SUB子程序。其中GOSUB语句是沿袭早期的BASIC语言版本,而SUB则是Quick BASIC对早期BASIC版本的重要扩展。
早期的BASIC版本只能使用GOSUB语句调用和主程序同在一个模块内的子程序,没有提供独立的子程序模块。
GOSUB是Goto Subroutine的缩写,意思是转到“子例行程序”中,执行一个子程序如同“例行公事”一样。整个“子例行程序”简称块内子程序或者子程序。它的主要特征是:子程序与主程序在同一程序模块中,根据调用方式上的不同,Quick BASIC对块内子程序有3种调用方式,对应的则用3种语句来实现。
格式:
GOSUB〈子程序入口〉
RETURN
功能:调用块内的子程序。
说明:
(1)GOSUB语句是写在调用程序中的语句:〈子程序入口〉是指子程序第一条语句的行号或者标号。
(2)RETURN语句应写在子程序中。
(3)GOSUB语句称为转子语句,其作用将流程转到子程序;RETURN语句称为返回语句,其作用是使流程和所有子程序中对应GOSUB语句的下条语句。
(4)主程序和块内子程序是连续书写的。它们是在同一模块之中,如果一个程序包含多个子程序,那么主程序和所有子程序都应写在同一模块中。子程序的范围是:从GOSUB语句指定的行号或者标号开始,到RETURN语句结束。
(5)变量在整个程序中有效。这就是说,变量在模块内的主程序和子程序中都是有效的。
[例9-9] 求3!+4!+5!的值。
问题分析:由于题中要求计算三个数的阶乘,再累加。而求阶乘的过程都是一样的,这样就把求阶乘的操作设计成子程序,每次分别以不同的值代入求得即可。
程序为:
'EXAMPLE 9
s=0
a=3
b=4
c=5
n=a
GOSUB f:
s=s+p
n=b
GOSUB f:
s=s+p
n=c
GOSUB f:
s=s+p
PRINT "3!+4!+5!=";s
END
f:p=1 '求阶乘子程序
FOR i=1 TO n
p=p*i
NEXT i
RETURN
程序运行结果为
3!+4!+5!=150
该语句是根据给定的条件进行判断,从多个子程序中选定其中一个执行。
格式:
ON〈算术表达式〉GOSUB〈子程序表〉
功能:根据〈算术表达式〉的值进行判断,执行〈子程序表〉中的第几个子程序。
说明:
(1)〈子程序表〉是指多个子程序之间用逗号隔开,这里的子程序是指其子程序第一行的行号或标号。
(2)ON GOSUB语句的用法是根据ON后面表达式的值来决定执行哪个子程序。若表达式的值为1,则执行子程序1;值为2,则执行子程序2,其余类推。招待完指定的子程序语句后,流程返回ON GOSUB语句下面的一个语句继续执行。
(3)如果〈算术表达式〉的值不是整数,则按四舍五入处理;
如果〈算术表达式〉的值为0或者大于子程序中的个数,则越过该语句;
如果〈算术表达式〉的值为负,则系统将给出“Illegal function call”(非法函数调用)的出错信息。