一、学习目标
1.掌握模块化程序设计思想
2.掌握函数与子程序的定义及使用
3.理解全局变量与局部变量
4.了解参数的传送过程
二、教学重点
掌握模块化程序设计
三、教学难点
掌握函数与子程序的定义及使用
四、教学方法
1.演示法。
2.实践法。
五、教学手段与教学媒体
多媒体网络教室。
六、课时安排
1课时。
七、教学过程
“模块化程序设计”中的“模块”是指:完成程序全部或部分任务的独立源程序文件。
程序的每一个模块可以是子程序或函数,它是通过执行一系列语句来完成一个特定的操作过程,常称为“过程”。
“执行一个过程”——调用一个子程序或函数;
一、自定义函数
qbasic函数:
①标准函数
②自定义函数
③外部函数
1、单行自定义(def)函数
语句函数——用一个语句定义一个函数
(1).一般格式;
deffn<名字>(<参数>)=<表达式>
例1.已知圆的半径r,求圆的面积:s=πr2
deffns(r)=3.14159*r*r
printfns(3)
end
例2.deffns$=”thisisastring”
printfns$
例3. 求以下公式:
deffnc(a,b)=sqr(a*a+b*b)
printfnc(3,4)
(2).说明
• 函数名由两部分组成
fns
自定义函数标志(fn),用户定义名(一个字母s);
• 参数可有多个,但调用时的参数(实参)与定义时的
参数(形参)要一致。
2、多行自定义(def)函数
用多行语句来定义一个函数。
(1)、一般格式
def fn<名字>(<参数>)
......
fn<名字>=<表达式>
end def
例4、定义函数f(n)=1+2+...+n
deffns(n)
s=0
fori=1ton
s=s+i
nexti
fns=s
enddef
forn=1to100
printfns(n)
nextn
end
(2)、说明
(i)形式参数——定义函数的自变量
实际参数——调用函数时的参数。
(ii)函数先定义后使用,即习惯把def语句
放在程序的开头。
二、块内子程序
1、gosub-return语句
子程序定义:
<标号或行号>:
......
return
子程序调用:
gosub<标号或行号>
例5:求4!+5!+6!
s=0
n=4:gosubf:s=s+p
n=5:gosubf:s=s+p
n=6:gosubf:s=s+p
print“4!+5!+6!=”;s
end
f:p=1
fori=1ton
p=p*i
nexti
return
2、ongosub-return语句
(1).一般格式
子程序定义:
<标号>:
......
return
子程序调用:
on <表达式>gosub<子程1>,<子程2>,…,<子程n>
例:“小学生算术练习”——轮流出一个二位数和一个一位数的加法、减法和乘法的题目,共出十题,每题10分。
randomize
fori=1to10
a=int(90*rnd)+10
b=int(9*rnd)+1
p=imod3+1
onpgosoba1,a2,a3
nexti
print"n=";n*10
end
a1:printa;"+";b;"=";共
inputc
ifc=a+bthenn=n+1
return
a2:printa;"-";b;"=";
inputc
ifc=a-bthenn=n+1
return
a3:printa;"*";b;"="
inputc
ifc=a*bthenn=n+1
return.
(2)、说明:
<表达式>的值不是整数时,按四舍五入处理,值为0或大于n则不起作用,值为负时系统给出错误信息——“不正确的函数调用”。
3、onkey(n)gosub-return语句
(1)、调用格式
onkey(n)gosub<标号>
其中n是数值表达式,代表一个“陷阱键”。n的值与 设定键的对应关系如下:
n值 键名
1~10 功能键f1~f10
11 方向键↑
12 方向键←
13 方向键→
14 方向键↓
例:求和式:s=12+22+...+n2 n=100000
onkey(2)gosubpri
key(2)on
s=0
fori=1to100000
s=s+i*i
nexti
pring“s=”;s
end
pri:print“nowswmis”;s,”i=”;i
return
(2).说明
设置陷阱:onkey(n)gosub<标号>
打开陷阱:key(n)on
关闭陷阱:key(n)off
三、独立模块的子程序
1、建立子程序
格式:sub<子程序名>[(<参数表>)]
………
endsub
2、子程序的调用
(1).格式
declaresub<子程序名>[(<参数表>)]
………
call<子程序名>[(<参数表>)]
或<子程序名><参数表>
例:substars(n)
fori=1ton
print“*”;
nexti
endsub
_________________________
declaresubstars(n)
callstars(30)
callstars(18)
end
(2).说明
i)declare为外部子程序说明语句,主程序调用多少个子程序,就有多少个declare语句;
ii)call语句的“call”可以省写,参数的括弧也
可不写;
如:callstars(30)
可写成:stars30
3、参数传递
(1).值传递方式
callstars(30)
......
substars(n)
(2).地址传递方式
a=30
callstars(a)
......
substars(n)
例:求4!+5!+6!+7!
子程序:subfact(n,f)
f=1
fori=1ton
f=f*i
nexti
endsub
主程序:declaresubfact(n,f)
fori=4to7
callfact(i,f)
s=s+f
nexti
print“s=”;s
end
注:地址传递方式是当实际参数为变量时发生,它将可能会改变原变量的值,若实际参数是变量时,又不想用地址传递(即用值传递方式)则可把变量用括号括起来。
例:求两个整数的最大公约数和最小公倍数。(p208) 最小公倍数=(m*n)/最大公约数
求最大公约数子程序:
subhcf(m,n,h)
ifm<nthenswapm,n
r=mmodn
dowhiler<>0
m=n
n=r
r=mmodn
loop 共
h=n
endsub
求最小公倍数子程序:
sublcm(m,n,h)
h=m*n/h
endsub
主程序:
declaresubhcf(m!,n!,h!)
declaresublcm(m!,n!,h!)
input"m,n=";m,n
callhcf(m,n,h)
print"最大公约数为:";h
calllcm(m,n,h)
print"最小公倍数为:";h
end
说明:程序在执行时,结果不正确;其原因是callhcf语句调用时修改了m和n的值,以至使calllcm运行不
正确。因此,callhcf语句应为:
callhcf((m),(n),h)例:验证哥德巴赫猜想:一个不小于6的偶数可以表示为两个素数之和。(p209)
算法:n=10
n1 n2
2(t) 8(f)
3(t) 7(t)
n=16
n1 n2
2(t) 14(f)
3(t) 13(t)
四、模块化的函数
1、建立一个函数
function<函数名>(<形参表>)
......
let<函数名>=<表达式>
endfuwstion
2、函数的调用
与标准函数相同,只是在主程序开头加上declare function<函数名>(<参数表>),无参数函数也要写上两个括号();例:求4到7的阶乘之和
functionfact(n)
f=1
fori=1ton
f=f*i
nexti
fact=f
endfunction
__________
declarefunctionfact(n)
s=0
fori=4to7
s=s+fact(i)
nexti
print"s=";s
end
注意函数的参数传递
3、static选项(静态)
外部函数中使用的变量,在函数调用结束后将全部被释放,其值不再保留。如要保留函数中的变量,可在建立函数时加写“static”即 funtion函数名(<参数>)static五、全局变量与局部变量
1、局部变量
每一个模块(子程序、主程序、函数)中的变量都只在本模块中有效,即是它们的作用域只限于模块,这种变量称为局部变量。2、全局变量
在程序所有模块中都有效的变量,即作用域为整个程序变量称为全局变量。其定义格式为:
commonshared<变量表>
六、过程的嵌套调用
在一个过程里又调用另一个过程。
七、过程的递归调用
在一个过程里又调用该过程本身;
例如直接调用:
functionf(x)
c=f(x)
f=2*c
endfunction
又如交叉调用:
functionf1(x)
……
c=f2(y)
……
f1=2*c
……
endfunction functionf2(t)
……
d=f1(a)
……
f2=4/d
……
endfunction
执行的结果造成无终止的自身调用,显然,程序中不应出现这种无终止的调用,而只应是有限次数的、有终止的递归调用。
fonctionage(n)
ifn=1thenage=10elseage=age(n-1)+2
endfonction
主程序:declarefunctionage(n)
printage(5)
end
fonctionfact(n)
ifn<=1thenfact=1elsefact=n*fact(n-1)
endfonction
教学后记:
共