BT-Basic编程系列–9–子程序和函数
9.1.子程序
我们可以将一段固定且常用的代码封装成一个子程序,在有需要的时候用call
进行调用。
call TEST
end
sub TEST
for I = 1 to 5
print I
next I
subend
运行结果:
1
2
3
4
5
子程序也是可以传参的,但一般少用,下面这段代码展示的是子程序传参在某些时候会出现一个巨坑:
A = 10
print "before call A=";A
call TEST(A)
print "after call A=";A
end
sub TEST(B)
B = 100
subend
运行结果:
before call A= 10
after call A= 100
从结果来看,传过去的参数如果在子程序中被重新赋值,那么回到主程序中,传过去的变量已经被改变。
看上去有点像传递一个指针。
我们大概地讲一下形参与实参的概念和区别,方便我们更好地理解:
- 形参的英文名:
parameters
,简写pars
;实参的英文名:arguments
,简写args
。 - 从使用角度来讲,形参就是将值传递给函数或子程序,在函数和子程序中才进行实例化,它在内存中的地址不是同一个;而实参就是把指针或是说内存的地址传递给函数或子程序,它在内存中的地址是一致的,在函数或子程序中对其进行修改都会影响到内存中的值,跟全局变量的性质相似。
A = 10
print "before call A=";A
call TEST1(A)
print "after call TEST1,A=";A
call TEST2
print "after call TEST2,A=";A
end
sub TEST1(B)
B = 100
subend
sub TEST2
A = 200
subend
运行结果:
before call A= 10
after call TEST1,A= 100
after call TEST2,A= 100
从上面这个例子来看,TEST2中的A跟主程序中的A只是名称相同,但不是同一个东西,这个就是变量的作用域。
在BT-Basic中,如果子程序要使用主程序中的变量,可以通过global
进行声明。
A = 10
print "before call A=";A
call TEST1(A)
print "after call TEST1,A=";A
call TEST2
print "after call TEST2,A=";A
call TEST3
print "after call TEST3,A=";A
end
sub TEST1(B)
B = 100
subend
sub TEST2
A = 200
subend
sub TEST3
global A
A= 300
subend
运行结果:
before call A= 10
after call TEST1,A= 100
after call TEST2,A= 100
after call TEST3,A= 300
在BT-Basic中参数最多可以是31
个,但是为了避免造成逻辑错误,一般都是用全局变量来给子程序传递数据。
因为在调用子程序的时候,传递过去的都是实参,在内存中的地址是同一个,如果不能理解这其中原理的人来看这样的程序,读起来会特别困难。别不信,由于子程序中没有return
这个概念,如果要实现应该要怎么办,下面这段代码可以实现类似功能:
A = 10
B = 20
call TEST(A,C)
call TEST(B,D)
print "C=";C
print "D=";D
end
sub TEST(ONE,TWO)
TWO=ONE*5
subend
运行结果:
C= 50
D= 100
一般不要用这种,除非你想写一个别人看不懂的程序,出错不好排解。
写程序嘛,实现一个功能写得越简单越好,特别是这种不用编译又不用太注重运行效率的,不用炫技,方便他人就是方便自己。
另外,子程序也可以用goto
,但有几点要注意:
- 子程序可以用
goto
,但仅限跳转在其内部的标签。 - 子程序不可以调用它自己,也就是递归调用。
- 可以嵌套,
exit
以后先出的原则。
9.2.函数
函数指的是一段具有输入和输出并完成指定功能的代码。也可以看做是命名有特殊要求且有返回值的子程序。
- 函数名以
fn
开头,如果返回值是字符串的话,函数名还必须以$结尾。 - 传参也是实参。
- 可以执行递归调用。
- 函数中可以有标签,但只作用于函数内。
- 只要遇到了
return
就会将值返回并退出函数。
for I = 1 to 5
print fnTEST(I)
next I
end
def fnTEST(A)
return A*5
fnend
运行结果:
5
10
15
20
25
总结
一般来说,一个可以执行的程序,在主程序中会有一个end
结尾。程序执行以第一行作为起点,以end
作为结束。程序主体通过调用各种子程序或函数实现所需功能。