不起眼的“陷阱”

Author: 广西 王那成 Date: 1995-05-26

        BASIC程例分析
        据调查,目前在计算机应用等级考试中,大部分考生选用BASIC解题,如果遇到以下两个BASIC程序的话,说不定会有相当多的人“阴沟里翻船”。
        例1. 求1+1/3+1/5+…+1/(2n-1),直到最后一项小于10-3为止。
        如果程序为
        10 N=1:M=0
        20 IF A<0.001 THEN 60
        30 M=M+A
        40 N=N+1: A=1/(2*N-1)
        50 GOTO 20
        60 PRINT M
        70 END
        运行的结果为0。显然这样的结果是错误的,问题出在哪里? 我们来看程序的执行顺序:10→20→30→…,在20句执行时,因A未被赋初值,因此按照BASIC的语法规则,A被自动赋初值为0,于是,程序的执行顺序实际上是10→20→60→70,其中的40句中对A的值的改变不可能实现,因此出错。正确的做法应该里在第10句加上A=1。即10 N=1: M=0: A=1
        由此例可以看出,对程序中的变量,都需先赋初值后使用;同时,检查程序出错,从变量值入手,这是常用的基本方法。
        下面来看另一个例程,程序的错误不易发现,很容易被看作是格式好坏的问题。
        例2. 计算选票程序(某班49个人选三个候选人之一为班长)
        程序如下:
        10  Z=0: L=0: W=0
        20  WPUT "A=";A
        30  IF A>3 OR A<=0 THEN PRINT "输入错误,请重新输入!"
        40  IF N=49 THEN 400: N=N+1
        50  ON A GOTO 100,200,300
        100 Z=Z+1: GOTO 20
        200 L=L+1: GOTO 20
        300 W=W+1: GOTO 20
        400 PRINT Z,L,W:END
        程序每一行的功能似乎很清楚,10行将三个候选人的原始票数赋为零;40行设置一个累加器,使49个人投完票后打印出各候选人的得票数;50-300行用了多分支选择语句,分别累计三个候选人的得票数。运行,发现久久算不出结果。强行中止(Ctrl-Break),设置跟踪(F7),再次运行,才发现问题出在40句,将40行冒号后的N=N+1语句作为45行,再次运行,终于使程序正确执行。
        原来,执行第40句时,在N未达到49时,执行的下一条语句是50而不是N=N+1, 这样,N的累加实际不成立,程序的循环就无法终止,使得程序没有结果。因冒号常用于一个语句中分隔若干个短小的语句,在语法上无错,因而不易引起怀疑,是一个不起眼的陷阱。然而,所有程序错误都是有方法找到的,象这类短小的程序,我们可以顺着程序“走”一遍,就会很容易发现错误的。
        以上程序在386SX兼容机,GWBASIC 3.22通过。