一个较大的程序一般分为若干个程序模块,每一个模块用来实现一个或几个特定的功能,这就是模块化的程序设计思想。由于模块就是能完成程序全部功能或部分功能的独立的源程序代码,也就是子程序或函数。本章重点内容有:
n 模块化程序设计的概念
n 自定义函数
n 独立模块的子程序
在编制程序时,经常遇到这样的情况,有些运算经常重复进行,或者许多人的程序中都可能要进行同类的运算操作。这些重复运算的程序是相同的,只不过每次都以不同的参数进行重复罢了。如果多注重书写执行这一功能的程序段,将使程序变得很长,多占存储空间,繁琐而又容易出错,并且调试起来比较困难。
解决这类问题的有效办法是将上述重复使用的程序,设计成能够完成一定功能的可供其他程序使用(调用)的相对独立的功能模块。它独立出去,即使只执行一次的程序段也可以把它写成独立模块,并把程序应该完成的主要功能都分配给各模块去完成,用主程序把各独立模块联系在一起。
这种设计方法是各种高级语言程序设计中的基本方法,好自顶向下、逐步细化和模块化。其中模块化的具体做法是:将一个大型程序按照其功能分解成若干个相对独立的功能模块,然后再分别进行设计,最后把这些功能模块按照层次关系进行组装。
使用独立模块的优点有:
(1)消除重复的程序行。可以一次性定义一个独立模块并可由其他程序任意调用。
(2)程序容易阅读。分解为一组较小的程序容易阅读和理解。
(3)使程序开发过程简化。独立模块容易设计、编写和调试。
(4)可以在其他程序中重用。可以把具有通用性的独立模块用在其他程序设计项目中。
(5)使Quick BASIC语言得到扩充。独立模块可以完成内语句和函数不能直接完成的任务。
独立模块由顺序、选择、循环这3种基本结构所组成,但它却有自己的特点,主要体现在主程序与独立模块之间的数据输入、输出,好主程序与各模块之间的数据传递。
由于模块是通过执行一组语句来完成一个特定的操作过程,所以模块又称为“过程”,执行一个过程就是调用一个子程序或函数模块。
Quick BASIC中功能模块统称为过程,分为函数(FUNCTION)过程和子程序(SUB)过程。
Quick BASIC语言提供了两种形式的函数。
用户可以直接调用而不必预先定义它,如SIN、INT、SQR函数等就是系统提供的标准函数。标准函数其实就是由Quick BASIC系统编成的一个个子程序,用户在使用时只需写出它们的名字(即函数名)和自变量就可以直接引用。例如,要计算某数x的平方根,只要写出SQR(x)即可。
Quick BASIC中标准函数调用的一般格式为:
格式:函数名[(〈函数参数〉)]
标准函数的使用说明:
(1)函数名是指标准函数的名字,如SQR、SIN、EXP、FIX、RND等。
(2)〈函数参数〉就是函数的自变量,又称“形式参数”,可以是一个常量、变量或表达式。如SIN(3+4)、SQR(4*8-2/5)等,自变量必须用括弧括起来。
(3)一个数学函数的值是一个数值,它可以参加运算,如:
2+SQR(8)+EXP(2)/FIX(-3.48*6)
但标准函数不能单独作为一个语句,如下面的写法是非法的Quick BASIC语句:
INT(RND*100+1)
它只是一个自变量为一个算术表达式的标准函数调用。
Quick BASIC标准函数包括数值函数、字符串函数和系统函数等,各有其不同的功能。具体函数名和功能见附录。
Quick BASIC语言同其他高级语言一样,允许用户根据实际问题的需要以一定的形式定义自己的专用函数,并且在程序中像调用标准函数一样方便地调用它。
Quick BASIC中的自定义函数又分为两种:
(1)模块内使用的自定义函数—DEF函数,它只在本模块有效。
(2)作为一个独立模块的外部函数—FUNCTION函数,它是一个独立的模块,而不是其他模块的一部分。
DEF函数又称为模块内使用的自调用函数,它只在本模块内有效。
格式:
DEF fn〈函数名〉[(〈参数表〉)]=〈函数表达式〉
功能:定义一个在本模块内有效的单行DEF函数。
说明:
(1)〈函数名〉是用户为此函数确定的函数名,它遵循变量名的命名规则。
(2)〈参数表〉用以指定函数表达式中的自变量,它可以是一个,也可以是几个,各参数之间用逗号分隔,每一个参数的格式为:
〈变量名〉[AS〈类型〉]
类型为变量的数据类型。
在调用时应代入实际的参数值。
(3)〈函数表达式〉是所定义函数的具体表达形式,它的类型应该与左边所定义函数的类型一致。
(4)自定义函数由两部分组成,例如定义一个求圆面积的函数s=πr2:
DEF fns(r)=3.14*r^2
其他fn是自变量的标识,不可缺少,即该语句定义的自定义函数名是fns,而不是s。在调用自定义函数时应将函数名的两部分及函数自变量的实际值同时写上。如上例中应写fns(10),不能写s(10)。
(5)自定义函数可以没有参数,例如:
DEF fna$="I am a student."
PRINT fna$
END
运行时输出为
I am a student.
[例9-1] 求半径为1,10,0,5,8时的圆面积。
问题分析:题中半径给定为1,10,20,5,8,要求分别求出相应的圆面积值。由于计算圆面积的方法都是一样的,我们将其设计成自定义函数fns。程序如下:
'EXAMPLE 1
DEF fns(r)=3.14*r^2
FOR i=1 TO 5
READ r
PRINT "半径为";r;"时的圆面积为";fns(r)
NEXT i
DATA 1,10,20,5,8
END
程序运行结果为:
半径为 1 时的圆面积为 3.14
半径为 10 时的圆面积为 314.00
半径为 20 时的圆面积为 1256.00
半径为 5 时的圆面积为 78.50
半径为 8 时的圆面积为 447.45
[例9-2] 现有两个矩形,已知一个矩形的长和宽分别是2和3,另一个矩形的长和宽分别是10和20,分别求这两种矩形的面积及其和。
程序如下
'EXAMPLE 2
DEF fnj(c,k)=c*k
PRINT "长和宽为2和3时矩形面积是";fnj(2,3)
PRINT "长和宽为10和20时的矩形面积是";fnj(10,20)
s=fnj(2,3)+fnj(10,20)
PRINT "两矩形的面积和是";s
END
程序运行结果为
长和宽为2和3时的矩形面积是 6
长和宽为10和20时的矩形面积是 200
两矩形的面积和是 206
[例9-3] 已知三角形的三边长为10,20,30,求该三角形的面积。
程序如下
'EXAMPLE 3
DEF fns(a,b,c)=SQR(s*(s-a)*(s-b)*(s-c))
a=20
b=30
c=40
s=(a+b+c)/2
PRINT"三角形的面积为";fns(a,b,c)
END
程序运行结果为
三角形的面积为 290.47
本例题中在定义函数时,表达式中有4个变量,3个是函数自变量a,b,和c,一个是程序变量s。在调用函数时只需给出变量a,b和c的。s的值由程序中的赋值语句进行赋值。另外,还要注意在调用函数fns时,参数的个数应和定义函数时参数的个数相同,例如,在语句DEF fns(a,b,c)=SQR(s*(s-a)*(s-b)*(s-c))中参数个数为3个,在调用时不能写成:
PRINT "三角形的面积为";fns(a,b,s)
简单的函数(用一个表达式表示的函数)是可以用单行DEF语句来定义的,因为函数可以在一行内写完。但是有的问题要求定义的函数是难以用一行来定义的(无用一个表达式个来表示),例如:

该函数就无法用单行DEF语句来定义。
为此,在Quick BASIC中提供了多行DEF来定义这类函数。
定义多行DEF函数的方法为
格式:
DEF fn〈函数名〉[(〈参数表〉)]
…
…
fn〈函数名〉=〈表达式〉
END DEF
功能:定义一个在本模块内有效的多行DEF函数。
说明:
(1)格式中的DEFfn和END DEF必须配套使用。
(2)〈函数名〉、〈参数表〉的含义与单行DEF语句相同。
[例9-4] 利用多行DEF函数,从键盘上输入x的值,求出下面分段函数中的y值。

程序如下:
'EXAMPLE 4
DEF fny(x)
IF x<0 THEN
fny=-x
ELSEIF x=0 THEN
fny=0
ELSE
fny=x
END IF
END DEF
INPUT "X=";x
PRINT "Y=";fny(x)
END
程序运行结果为
X=? -5
Y= 5
X=? 10
Y= 10
X=? 0
Y=0
[例9-5] 利用多行DEF函数求s=1+3+5+7+…+n的和。
问题分析:题中要求我们求出1到n之间的奇数和。n由键盘输入。
程序如下
'EXAMPLE 5
DEF fns(n)
s=0
FOR k=1 TO n STEP 2
s=s+k
NEXT k
fns=s
END DEF
INPUT "N=";n
PRINT "s=1+3+5+7+…+n的和为";fns(n)
END
程序运行结果为:
N= ? 7
s=1+3+5+7+…+n的和为 16
N= ? 9
s=1+3+5+7+…+n的和为 25
N= ? 100
s=1+3+5+7+…+n的和为 2500