背景:                 
[本书目录] [图书首页] [本书讨论区]  
链接地址:http://www.17xie.com/read-6168.html    注册17xie 一起来写书 实现您的出书梦想!

地址单元。当执行到CALL语句时,就调用子程序prod(),并把变量abc的值传给变量xyz。在子程序prod()中如果变量的z值发生变化,则返回主程序中,变量c的值随之改变。

9.4.3  传值调用

传值调用是把实际参数的值传递给对应的形式参数。它是把需要传送的实际参数的值复制到一个临时内存单元中,然后把该临时单元的地址传送给子程序。由于子程序没有访问实际参数的原始地址,因而不会改主原来参数的值,所有的变化都是在变量的副本上进行的。因此,在过程中无论形式参数如何改变,主程序中的实际参数不会受到影响。

当要求用变量按值传送时,可以先把变量变成一个表达式,例如把变量用括号括起来,如(a%)是一个表达式。

传值调用子程序的工作过程:

1)计算出实际参数的值。

2)子程序内使用的变量被定义为局部变量,在退出该子程序时即消失。与形式参数相对应的各变量按特殊的局部变量来处理。

3)实际参数的值复制给子程序中对应的形式参数。

4)继续执行子程序体中的语句。

5)退出子程序,子程序中所有局部变量消失。返回到主程序中执行子程序调用语句的下一语句。

[9-14]  阅读下面的程序,分析运行结果,理解传值调用。

主程序为:

EXAMPLE 14

DECLARE SUB prod(a!,b!,c!)

CLS

a=5:b=3

PRINT"主程序调用前的变量值a,b,c:",a,b,c

CALL prod((a),(b),(c))

PRINT "主程序调用后的变量值a,b,c",a,b,c

END

子程序为:

SUB prod(a,b,c)

PRINT "子程序中运算前的变量值a,b,c:",a,b,c

a=6:b=8

c=a*b

PRINT "子程序中运算后的变量值a,b,c:",a,b,c

END SUB

程序的运行结果为:

主程序调用前的变量值a,b,c:        5    3    0

子程序中运算前的变量值a,b,c:      5    3    0

子程序中运算后的变量值a,b,c:      6    8    48

主程序调用后的变量值a,b,c:        5    3    0

在子程序中即使与主程序中使用的变量名相同,但在内存中仍表示不同的内存单元地址。即执行子程序时使其变量内容发生变化,主程序中的变量内容并举随之改变。

在过程中以传值调用为主,如果希望把过程中的变量值返回主程序,才使用传址调用。

用传值调用这种传递参数的方法只能传递计算值,如数值、字符串、数值数组的值。

9.5  过程的嵌套和递归调用

Quick BASIC的过程定义都是互相平行和孤立的,也就是说在定义过程时,一个过程内不能包含另一个过程。Quick BASIC虽然不能嵌套定义过程,但可以嵌套调用过程,也就是主程序可以调用子过程,在子过程中还可以调用另外的子过程,这种程序结构称为过程的嵌套。

9.5.1  过程的嵌套

[9-15]  求组合数Cmn= 的值,设N10M6

在程序中我们把求阶乘与求组合数公式分别定义为函数。

主程序为:

'EXAMPLE 15

DECLARE FUNCTIONcomb!(n!,m!)

DECLARE FUNCTION fact!(x!)

CLS

INPUT"n,m=";n,m

PRINT"C(";n;",";m;")=";comb(n,m)

END

自定义函数为(求组合数)

FUNCTION comb(n,m)

comb=fact(n)/(fact(m)*fact(n-m))

END FUNCTION

自定义函数为(求阶乘)

FUNCTION fact(x)

==1

FOR i=1 TO x

==p*i

NEXT i

fact=p

END FUNCTION

程序的运行结果为:

C106)=210

FUNCTION子过程comb中调用了FUNCTION子过程fact,从而形成过程的嵌套。

9.5.2  过程的递归调用

递归调用是指一个过程直接或间接调用自己本身即自己调用自己。在递归调用中,一个过程执行的某一步要用到它自身的上一步(或上几步)的结果。

Quick BASIC过程具有递归调用功能,递归调用在处理阶乘运算、级数运算、幂指数运算等方面特别有效。

[9-16]  计算n!

根据数学知识,负数没有阶乘,0的阶乘为1,正整数n的阶乘为:

n×(n-1)×(n-2)×…×2×1

则可以用下式表示:

利用上式,把求n!转换为求n×(n-1)!

上面的公式说明了每一循环的结果都有赖于上一循环的结果递归总有一个“结束条件”,如n!的结束条件为n=0

Quick BASIC中用递归过程实现这种运算的程序如下。

主程序

'EXAMPLE 16

DECLARE FUNCTION factorial#(n%)

CLS

DO

INPUT"请输入一个0~20之间的整数(-1结束):"num%

IF num%>=0 AND num%<=20 THEN

PRINT num%,factorial#(num%)

END IF

LOOP WHILE num%>=0

END

自定义函数为:

FUNCTION factorial#(n%)STATIC

IF n%>0 THEN

factorial#=1

END IF

END FUNCTION

n%>0时,在过程factorial#中调factorial#过程,参数为n%-1,这种操作一直持续到n%=1为止。

例如,当n%=5时,求factorial#(5)的值变为求5×factorial#(4);factorial#(4)的值又变为求4×factorial#(3),,n%=0时,factorial#的值为1,递归结束,其结果为5×4×3×2×1。如果把第一次调用过程factorial#叫做0级调用,以后每调用一次级别增加1,过程参数n%1,则递归调用的过程如下:

递归级别                 执行操作

0                          factorial#(5)

1                            factorial#(4)

2                                factorial#(3)

3                                   factorial#(2)

4                                      factorial#(1)

4                          返回1       factorial#(1)

3                        返回2      factorial#(2)

2                      返回6      factorial#(3)

1                    返回24      factorial#(4)

0                  返回120    factorial#(5)

9.6  变量的属性和作用域

当所编写的程序越来越长时,程序中所使用的变量也会越来越多。为了帮助用户管理大量的变量,Quick BASIC规定了一些特殊的规则处理过程中的变量。Quick BASIC将变量分为全程变量、局部变量和共享变量3类,这3类变量的作用域也各不相同。

9.6.1  局部变量

Quick BASIC中使用的变量,凡未经特殊说明的变量均属于局部变量(Local Verable),局部变量在主程序、子程序或函数中建立,但是只能在建立的过程内有效,即便是在主程序中建立的变量,也不能在子过程中使用。

局部变量不用任何语句说明。它的作用域仅限于它自己所在的过程,使用局部变量的程序比仅使用全程变量的程序更具有通用性。

[9-17]  未经说明的局部变量示例。

主程序为:

'EXAMPLE 17

DECLARE SUB prod()

DECLARE SUB sum()

CLS

a=5:b=3

PRINT TAB(16);"a";TAB(30);"b";TAB(42);"c=a*6"

PRINT "调用prod"a,b,c

CALL prod

PRINT"调用prod"a,b,c

PRINT

PRINT"调用sum"a,b,c

CALL sum

PRINT"调用sum",a,b,c

END

子程序为:

SUB prod

c=a*b

PRINT"prod子程序",a,b,c

END SUB

子程序为:

SUB sum

c=a+b

PRINT "sum子程序",a,b,c

END SUB

程序的运行结果为:

a       b       c=a*b

调用prod                5       3       0

prod子程序                 0       0       0

调用prod                5       3       0

 

调用sum                 5       3       0

sum子程序                  0       0       0

调用sum                 5       3       0

从上面程序的运行结果可以看出,主程序中的变量没有带到子程序中。

9.6.2  全程变量

全程变量(Global Variable)是指在所有程序(包括主程序和过程)中都可以使用的内存变量。全程变量只能在主程序中定义,在主程序中用DIMREDIMCOMMON语句中的SHARED短语定义全程变量属性;全程变量就像在一个程序中定义的变量一样,可以任意改变和调用,当过程执行完后,其值仍然保留,并带回主程序。

把变量定义为全程变量虽然很方便,但这样会增加变量在程序中被无意修改的机会,因此许多程序员不赞成在程序中使用全程变量。

另外,在主程序中用CONST语句定义的符号常量也是全程的,即在各过程中可以引用该符号常量。过程中用CONST定义的符号常量都是局部的,只能在该一个过程内引用。

在主程序中,可用DIM SHAREDREDIM SHARED语句把某些变量或数组定义为全程变量,使该变量在主程序及各过程中到处可以使用和修改。用DIM SHAREDREDIM SHARED语句说明变量后,要在后面程序或过程中对变量用赋值语句赋值。

[9-18]  在主程序中用DIM SHARED语句来定义全程变量。

主程序为:

'EXAMPLE 18

DECLARE SUB prod()

DECLARE SUB sum()

CLS

DIM SHARED a,b,c

a=5:b=3

PRINT TAB(16);"a";TAB(30);"b";TAB(42);"c=a*b"

PRINT"调用prod",a,b,c

CALL prod

PRINT"调用prod"a,b,c

PRINT"调用sum"a,b,c

CALL sum

PRINT"调用sum"a,b,c

END

子程序为:

SUB prod

c=a*b

PRINT "prod子程序",a,b,c

END SUB

子程序为:

SUB sum

c=a+b

PRINT"sum子程序",a,b,c

END SUB

程序的运行结果为:

                                         a     b     c=a*b

调用prod                                 5     3     0

prod子程序                                   5     3     15

调用prod                                  5     3     15

 

调用sum                         5     3     15

sum子程序                      5     3     8

调用sum                    5     3     8

从程序的运行结果可以看出,在主程序中用DIM SHARED语句定义的全程变量abc,把值带到了子程序中;返回主程序时,把修改后的值又带回了主程序。

9.6.3  共享变量

Quick BASIC中还有一种特殊的使用变量的方式,就是在主程序中不用DIMREDIMCOMMON语句中的SHARED短语定义全程变量而在子程序中用SHARED语句来定义调用主程序中的同名变量,这种变量称共享变量(Sharing Variable)。用SHARED定义的变量可以在子过程中引用主程序中的变量,子过程中修改后的变量值也将带回主程序。

格式:

SHARED〈变量1〉[()][AS〈类型〉][,〈变量2〉[()][AS〈类型〉]]…

功能:定义过程中可以访问主程序中的变量。

说明:

1)〈变量〉是主程序中的变量名,也就是本子过程与主程序共用的变量名,可以是简单变量或数组变量。

2)〈类型〉用来定义对应〈变量〉的数据类型(INTEGERLONGSINGLEDOUBLESTRING或用户定义类型)。

3SHARED语句只能在SUBFUNCTION过程使用。SHARED后面列出的变量必须是主程序中存在的变量。

[9-19]  在子程序中用SHARED语句来定义共享变量。

主程序为:

'EXAMPLE 19

DECLARE SUB prod()

DECLARE SUB sum()

CLS

a=5:b=3

PRINT TAB(16);"a";TAB(30);"b";TAB(42);"c=a*b"

PRINT"调用prod"a,b,c

CALL prod

PRINT"调用prod"a,b,c

PRINT

PRINT"调用sum",a,b,c

CALL sum

PRINT"调用sum"a,b,c

END

子程序为:

SUB prod

SHARED a,b,c

c=a*b

PRINT"prod子程序",a,b,c

END SUB

子程序为:

SUB sum

c=a+b

PRINT"sum子程序",a,b,c

END SUB

程序的运行结果为:

a                b                 c=a*b

调用prod                5                 3                 0

prod子程序                 5                 3                 15

调用prod                5                 3                 15

调用sum                5          3          15

sum子程序             0        0         0

调用sum            5        3         15

从程序的运行结果可以看出,在子程序prod中定义了共享主程序中的abc变量,因此在子程序prod中可以引用和修改,返回主程序时也把修改后的变量值带回了主程序。子程序sum中的abc没有特别说明,都是局部变量,也就无法引用主程序中的变量。

9.6.4  变量作用域规则小结

Quick BASIC的变量作用域规则:

1)主程序中用DIMREDIMCOMMON语句中的SHARED短语说明的变量是全程变量,任何SUBFUNCTION都能调用这些变量。

2)主程序中用CONST语句说明的符号常量全程符号常量。在SUBFUNCTION中说明的符号常量是局部符号常量。

3)如果一个变量未经任何说明,则这个变量是局部变量 ,它只能在建立这个变量的主程序或过程内使用。

4)如果在一个过程内用STATIC语句说明一个全程变量名或者在一个过程内把全程变量当作形式参数,则这个全程变量名在这外过程中就作为局部变量。

5SHARED语句使主程序和子过程中同名变量成为共享变量。

9.7  静态变量与动态变量

比如子程序内部有一个变量,当程序运行进入该程序时,要分配给该变量一定的内存单元,一旦程序退出该过程,变量占有的内存单元是释放还是不释放?根据变量在程序运行期间的生命周期,Quick BASIC把变量分为静态变量(Static)和动态变量(Dynamic)。静态变量不释放内存单元,动态变量释放内存单元,因此有时就需要某些局部变量是静态变量,而其他变量仍然为动态变量。

所谓静态存储方式是指在程序运行期间分配固定的存储空间的方式。而动态存储方式则是在程序运行期间根据需要进行动态的分配存储空间的方式。

静态变量是指程序运行进入该变量所在的子程序,修改变量的值后,退出该子程序其值仍被保留,即变量所占内存单元没有释放。当以后再次进入该子程序,原来变量的值可以继

字数:12719    最后更新:1年以前 [08-24 10:36]我爱钱 修改
本页编辑者:我爱钱  
[前一页]:第九章  [后一页]:第九章
[在本页中加入书签] [收藏本书] [推荐本书]
  17xie论坛 > 本书讨论区 > 本页评论   (共0条)
发表评论

用户名称 匿名发表
评论内容
验证码

关于我们 | 版权声明 | 免责声明 | 诚聘英才 | 联系我们 | 合作伙伴 | 友情链接 | 广告合作 | 提交意见
Copyright © 2007 17xie.com 互联网协同写书平台 京ICP备08002671号