360 likes | 538 Views
QBASIC 语言. 第七章 函数和子程序. 本章重点 掌握模块化程序设计思想 掌握函数与子程序的定义及使用 理解全局变量与局部变量 了解参数的传送过程. 独立模块的子程序. 通常把要多次进行某操作的部分编写为子程序 整个程序由一个主程序和若干子程序组成 使程序结构清晰,可读性好 程序总是从主程序开始执行 通常把独立模块的子程序和函数称为 过程. SUB 子程序名 ( 形式参数 ) 子程序内容 END SUB. 定义子程序. 命名规则与变量相同 子程序通过形式参数来接受数据或传递数据 没有参数时括号必须省略
E N D
QBASIC语言 第七章 函数和子程序
本章重点 • 掌握模块化程序设计思想 • 掌握函数与子程序的定义及使用 • 理解全局变量与局部变量 • 了解参数的传送过程
独立模块的子程序 • 通常把要多次进行某操作的部分编写为子程序 • 整个程序由一个主程序和若干子程序组成 • 使程序结构清晰,可读性好 • 程序总是从主程序开始执行 • 通常把独立模块的子程序和函数称为过程
SUB 子程序名(形式参数) 子程序内容 END SUB 定义子程序 • 命名规则与变量相同 • 子程序通过形式参数来接受数据或传递数据 • 没有参数时括号必须省略 • 可以用EXIT SUB退出子程序 • 子程序内不能有DATA语句, DATA语句应放在主程序内 • 子程序内不能再有SUB行 演示QB7-1
DECLARE SUB STARS () CLS CALL STARS PRINT "*"; TAB(15); "*" CALL STARS PRINT "*"; TAB(15); "*" CALL STARS END SUB STARS FOR I = 1 TO 15 PRINT "y"; NEXT I PRINT END SUB
子程序的调用 CALL 子程序名(实际参数) 或 子程序名 实际参数 • 如省略CALL则必须省略括号,且子程序名和实参间应有空格 • 实参个数=形参个数,并按类型对应 • 实参可是变量,常量,表达式,函数 • 如无参数,括号必须省略 • 子程序之间可以互相调用 演示QB7-2
DECLARE SUB ST (N!) FOR I = 1 TO 6 CALL ST(I) NEXT I END SUB ST (N) PRINT TAB(10); FOR J = 1 TO N PRINT "*"; NEXT PRINT END SUB
子程序的建立 • 键入主程序部分 • 在主程序的后面输入 • SUB <子程序名>[(形参)] • 系统进入子程序窗口,出现 • SUB <子程序名>[(实参)] END SUB • 用F2切换程序与子程序
DECLARE 语句 • 是一个说明语句 • 它是在键入子程序后自动生成的 • 说明该主程序包含几个子程序、子程序的名字及形式参数 • 有几个子程序,就有几个DECLARE语句
模块间的数据传递 • 实参与形参的类型必须一致 • 值传递 • 是单向传递 • 形参与实参各占一个单元 • 形参的变化不影响实参值 • 实参是常量或表达式时,先计算表达式的值,然后把实参传递给形参 CALL ST(30) SUB ST(N) 演示QB7-3
DECLARE SUB st (n!) CLS CALL st(10) END SUB st (n) FOR i = 1 TO n PRINT "*"; NEXT i END SUB
模块间的数据传递 M • 在值传递中 • 实参是变量时应将实参括起来 M=10 CALL SUB2((M)) SUB SUB2(N) N=N+2 END SUB N 10 10 10 12
模块间的数据传递 • 地址传递 • 双向传递 • 实参将地址传递给形参 • 实参与形参共同占用一个存储单元 • 在主程序中实参占用存储单元 • 进入子程序后形参占用存储单元 • 子程序执行后,形参让出存储单元,将值传递给实参,实参占有该单元
a b 5 8 • 地址传递的形式 a=5:b=8 CALL sub3(a,b) SUB sub3(x,y) x=x+2 y=y+2 END SUB a , x b , y 5 8 a , x b , y 7 10 将任意三个数由小到大排序 a b 求4!+5!+6!+7! 7 10 QB7-4 QB7-5
DECLARE SUB SORT (A!, B!, C!) CLS INPUT "A,B,C="; A, B, C CALL SORT(A, B, C) PRINT A, B, C CALL SORT(A + B, B + C, C + A) PRINT A + B, B + C, C + A END SUB SORT (A, B, C) IF A > C THEN SWAP A, B IF A > C THEN SWAP A, C IF B > C THEN SWAP B, C END SUB
DECLARE SUB P (N!, T!) REM 4!+5!+6!+7! CLS SUM = 0 FOR I = 4 TO 7 CALL P(I, T) SUM = SUM + T NEXT I PRINT "SUM="; SUM END SUB P (N, T) T = 1 FOR I = 1 TO N T = T * I NEXT I END SUB
独立模块的函数的定义 FUNCTION 函数名(形式参数) [STATIC] 函数体 END FUNCTION • 当无形参时必须省略括号 • 函数名起名规则与变量相同 • 由函数名带回函数值,所以在函数中至少给函数名赋值一次,函数名本身有类型(加% , & , ! , # , $)
函数名在函数体内不能参与运算或输出 • 可用EXIT FUNCTION结束函数 • 函数体内不能有FUNCTOIN和SUB行 • STATIC用来指定函数中的变量为静态变量,调用函数结束后仍保留函数体中的值,作为下次调用该函数的初值 • 例:求三个整数的最大值 QB7-6
DECLARE FUNCTION MAX% (A%, B%, C%) INPUT "N1,N2,N3="; N1%, N2%, N3% PRINT MAX%(N1%, N2%, N3%) END FUNCTION MAX% (A%, B%, C%) IF A% > B% THEN M% = A% ELSE M% = B% IF C% > M% THEN M% = C% MAX% = M% END FUNCTION
函数名(实际参数) 或 函数名 模块化函数的调用 • 实参个数=形参个数,类型必须一一对应 • 实参可以是变量,常量,表达式 • 若函数没有形参,则括号必须省略 • 函数的调用不能作为一条独立语句 • 模块化函数的数据传递与子程序的数据传递方法相同
举例 • 用一个函数求圆面积。累计5个圆面积之和,在函数中累计调用函数的次数 • 运用STATIC参数 QB7-7 • 求4到7的阶乘之和 QB7-8
DECLARE FUNCTION area! (r!) SUM = 0 FOR i = 1 TO 5 SUM = SUM + area(i) NEXT i PRINT "SUM="; SUM END FUNCTION area (r) STATIC a = 3.14159 * r ^ 2 area = a n = n + 1 PRINT "n="; n, "area="; a END FUNCTION
DECLARE FUNCTION T! (N!) SUM = 0 FOR I = 4 TO 7 SUM = SUM + T(I) NEXT I PRINT "SUM="; SUM END FUNCTION T (N) F = 1 FOR I = 1 TO N F = F * I NEXT I T = F END FUNCTION
函数与子程序的区别 • 函数是通过函数名回送一个结果值,仅用于计算单个函数值 • 子程序的结果由实参带回,可以包括多个结果 • 函数的调用出现在表达式中,而子程序的调用必须作为一个单独的语句
块内子程序 求 GOSUB 行号或标号 • 子程序内至少有一个RETURN语句 • 主程序与子程序的变量在整个程序中都有效 块内函数 DEF FN函数名(参数)=表达式 或 DEF FN函数名(参数) 定义 END DEF 演示QB7-9,QB7-10,QB7-11
INPUT "m,n(m>n)="; m, n k = m: GOSUB a c = t k = n: GOSUB a c = c / t k = m - n: GOSUB a c = c / t PRINT "C="; c END a: t = 1 FOR i = 1 TO k t = t * i NEXT i RETURN
求扇形面积 y=(x^2+x+1)^2+(x^2+x+1)+1 x=2 的值 CLS REM a:corner DEF fns (r) = r * r * a / 2 a = 3.14 / 3 PRINT fns(2), fns(3), fns(4) END CLS DEF fnf (x) = x * x + x + 1 x = 2 y = fnf(fnf(x)) PRINT "x="; x, "y="; y END
求三角形的面积 Def fns(a,b,c)=(a+b+c)/2 Def fna(a,b,c)=(fns(a,b,c)-a)*fns(a,b,c)- b)*fns(a,b,c)-c) Def fnarea(a,b,c)=sqr(fns(a,b,c)*fna(a,b,c)) Print “area=”;fnarea(3,4,5) end
局部变量和全局变量 • 局部变量:只在本模块中有效的变量 • 全局变量:在所有模块中都有效的变量 • 不加以全局说明的变量都是局部变量 • DIM SHARED • 对数组做全局说明 • COMMON SHARED • 对变量做全局变量说明 • 全局变量不能重复定义,且只能在主程序中定义,必须在所有可执行语句前定义 演示QB7-12 ,QB7-13,QB7-14
DECLARE SUB AREA () R = 10 PRINT "R="; R CALL AREA END SUB AREA S = 3.14 * R * R PRINT "R="; R, "AREA="; S END SUB
DECLARE SUB AREA (R!) CALL AREA(10) END SUB AREA (R) S = 3.14 * R * R PRINT "R="; R, "AREA="; S END SUB
DECLARE SUB AREA () COMMON SHARED R CLS R = 10 PRINT "R="; R CALL AREA END SUB AREA S = 3.14 * R * R PRINT "R="; R, "AREA="; S END SUB
过程的嵌套 • 在一个过程(函数或子程序)执行的过程中又调用另一个过程 • 例求 调用求上述组合的函数 Cmn(m,n) 在求组合的函数中调用求阶乘的函数 t(k) QB7-15
过程的递归调用 4! N!=N*(N-1)! 既过程直接或间 接地调用自己 4* 3! Function f(n) if n<=1 then f=1 else f=n*f(n-1) End function Declare function f!(n!) Input “n=” ;n Print “n!=”; f(n) : end 3* 2! 2* 1! 1 演示7-16
本章小结 • 模块化程序设计的应用 • 函数与子程序的设计思想 • 利用参数传递形式程序 • 全局变量与局部变量的使用 习题 • 228页 • 1, 2, 9, 17