在这次解答栏里,首先给读者提供两个错误的程序。请读者先找一下程序错在哪里,然后在程序下面说明,以免今后犯同样的错误。
〔例1〕编一程序,从以下10个数中挑出最大的数,并输出。
6,22,-10,0,19,63,-28,-3,2,-6
程序如下:
10 DIM A(10)
20 FOR I=1 T0 10
30 READ A(I)
40 NEXT I
50 FOR I=1 T0 10
60 IF A(I+1)>=A(I) THEN 100
70 T=A(I)
80 A(I)=A(I+1)
90 A(I+1)=T
100 NEXT I
110 PRINT A(I)
120 DATA 6,22 -10,0,19
130 DATA 63,-28,-3,2,-6
140 END
这个程序的编写思路是这样的,先由语句10定义一个数组A(10),然后由语句20、语句30和语句40组成的单重循环将DATA语句数据区中的10个数分别读入数组A(10)的10个数组元素中(未使用数组元素A(0))。挑选最大数由语句50到语句100这个程序段完成。在循环体内,先由语句60判断A(1)和A(2)中的数哪一个大。如果A(2)中的数小,就由语句70、语句80和语句90来交换两数组元素的值,然后接着往下比较A(2)和A(3)中的数;如果A(2)中的数不小于A(1)中的数,就直接转去比较A(2)和A(3)中的数,依次类推……。比较完后,A(10)中装的数就一定是最大的数了。但这个程序在确定比较次数时出现了漏洞,让我们看一下语句50,循环终值是10,当I取值10时,语句60中的A(I+1)即A(11),这超出了数组A(10)的定义范围,A(11)是没有被定义的数组元素,所以,程序错在循环终值的选取上,应改为9。即改正后的语句50变为
50 FOR I=1 TO 9
退出循环后,语句110输出A(I)的值(即A(10)的值)正是10个数中的最大数。
〔例2〕编一程序,将1至15间的每个奇数连续输出三遍。
程序如下:
10 FOR X=1 TO 15 STEP 2
20 GOSUB 100
30 NEXT X
40 END
100 FOR X=1 TO 3
110 PRINT X,
120 NEXT X
130 RETURN
这个程序的编写思路是这样的,在主程序中挑出1至15间的各个奇数,每挑出一个奇数,便转去执行子程序,由子程序负责将该奇数输出3遍。这种设计思想是很好的,但为什么运行这个程序,它一行接一行地不断输出1、2、3这3个数呢?仔细观察一下主程序和子程序,便可以发现:两者中的循环控制变量都是X,在主程序中挑出的奇数(存在X变量中),被子程序改变了。所以,应当改变子程序的循环控制变量,改正后的程序为:
10 FOR X=1 TO 15 STEP 2
20 GOSUB 100
30 NEXT X
40 END
100 FOR I=1 TO 3
110 PRINT X,
120 NEXT I
130 RETURN
以上我们分析了两个有错误的程序,下面再具体解几道题。
〔例3〕编一程序,要求做到对任意输入的长度不大于239的串,统计出其内含多少个A。
程序的设计思路如图所示。首先将计数器清零,然后任意输入一个串,并求出该串的长度作为循环语句的终值。在循环体内逐个挑出每个字符加以判断,如果挑出了一个A,便将计数器加1。最后,退出循环输出所统计的A的个数。根据框图写的程序如下:

10 K=0
20 INPUT A$
30 L=LEN(A$)
40 FOR I=1 TO L
50 B$=MID$(A$,I,1)
60 IF B$=“A” THEN K=K+1
70 NEXT I
80 PRINT K
90 END
〔例4〕编一程序,对从键盘输入的任意正整数(不允许超出计算机的正整数域),求出其位数和最高位数字。
如何求出某一正整数的位数呢?解法思路是这样的:首先判断一下该正整数是否小于10,如果小于,则说明位数是1;如果不小于,再去判断该正整数是否小于100,1000,……依次类推。所写的程序如下:
10 K=1
20 INPUT M
30 IF M<10↑K THEN 60
40 K=K+1
50 GOTO 30
60 PRINT K
70 PRINT INT(M/10 ↑(K-1)
80 END
程序中,变量M用来计算正整数的位数,首先假设位数为1,语句20将正整数存入变量M中。语句30首先判断M中的值是否小于10,如果不小于,便由语句40将位数加1,然后又转回语句30判断M中的值是否小于10\(^{2}\),……一旦找到某一个K值,使得M<10K成立,则说明M中值的位数即为K。语句60负责输出位数,语句70输出的是该正整数的最高位数字。这道题还有其它解法,读者不妨试着做一下。(蒙濛 刘雨)