第4章 结构化程序设计

4.1 判断题

1.在Visual FoxPro中,命令文件的扩展名为.fxp。

【答案】×

【分析】Visual FoxPro命令文件的扩展名为.prg,.fxp是执行程序时自动编译生成的目标文件扩展名。

2.结构化程序设计的三种基本结构是选择、分支和循环。

【答案】×

【分析】结构化程序设计的三种基本结构是顺序、选择(或称分支)和循环。

3.在Visual FoxPro的分支或循环语句中的条件表达式就是逻辑表达式。

【答案】×

【分析】分支或循环语句中的条件表达式的结果应该为逻辑值,而表达式一般分为数值表达式、字符表达式、日期表达式、逻辑表达式和关系表达式,其中逻辑表达式和关系表达式的结果都是逻辑值,所以分支或循环语句中的条件表达式可以是逻辑表达式或关系表达式。

4.在多分支DO CASE语句中,必须有一个条件表达式成立。

【答案】×

【分析】当DO CASE语句中所有条件都不满足时,执行OTHERWISE下的语句序列;如果没有OTHERWISE,则跳过多分支DO CASE语句,执行ENDCASE后面的语句。

5.EXIT和LOOP语句一定出现在循环中。

【答案】√

【分析】EXIT语句的功能是用于结束当前循环操作,跳到循环结束语句的后面;LOOP语句的功能是用于跨过LOOP后面的语句,直接回到循环起始语句。根据它们的功能就知道这两个语句一定出现在循环体中。

6.SCAN-ENDSCAN循环结构具有自动移动记录指针的功能。

【答案】√

【分析】SCAN-ENDSCAN循环结构的功能是对当前打开的表文件在指定范围、满足条件的记录中进行自上而下逐个扫描操作,逐个扫描就具有自动移动记录指针的功能。

7.在FOR循环语句中,ENDFOR是不可缺少的。

【答案】√

【分析】Visual FoxPro的分支和循环结构语句都是配对出现的,FOR和ENDFOR是一对。

8.在FOR循环语句中,STEP步长可以是小数。

【答案】√

【分析】根据说明,FOR循环的初值、终值和步长均为一个数值表达式,其值可为正数、负数或小数。

9.程序中出现多种嵌套结构时,嵌套只能包含,不得交叉。

【答案】√

【分析】对于任何结构的嵌套,都要注意两点,一是嵌套不能交叉,二是语句是配对出现的,不能忘记各种结构的结束语句,否则,嵌套交叉后逻辑关系就乱了。

10.过程是一段独立的程序段,而过程文件则是存放过程的文件。

【答案】√

【分析】根据过程文件及过程的定义:过程文件是存放若干子程序的文件,可以理解为若干子程序的打包。存放在过程文件中的子程序不再称为子程序而称为过程,子程序是一段独立的程序段。

11.过程文件与其中的过程都使用同一个名称。

【答案】×

【分析】每个过程文件有一个名称,其文件类型是.prg,过程文件中的每个过程都有自己的过程名,一般用“PROCEDURE过程名”来定义。

12.PUBLIC定义的变量是局部变量。

【答案】×

【分析】PUBLIC定义的变量是全局变量,具有公共属性;而局部变量有三种属性,即自然属性、私有属性和本地属性。

13.在自定义函数调用时,在传递参数变量前加“@”则为传值的方式。

【答案】×

【分析】自定义函数的参数传递既可以用传值的方式,也可以用引用的方式。默认是传值的方式。如果在传递参数变量前加“@”则为引用的方式。

14.调用过程和调用自定义函数方法完全相同。

【答案】×

【分析】调用过程用DO命令,自定义函数虽然是一个子程序,但是不能用DO命令调用,而只能像系统函数一样用输出语句(?,??)输出或出现在表达式中。

15.自定义函数中只有一种方法传递回结果:RETURN <表达式>。

【答案】×

【分析】自定义函数除了可以用RETURN <表达式>传递回结果外,还可以用引用的方式通过函数自变量将结果传递回来。

4.2 选择题

1.下面能输入数值型数据的命令是( )。

A.INPUT B.ACCEPT C.WAIT D.以上都可以

【答案】A

【分析】INPUT从键盘输入数据的类型可以是除备注型和通用型外的所有类型;ACCEPT从键盘输入的数据系统认定是字符型数据;WAIT从键盘只能输入单个字符。

2.不属于程序控制三种基本结构的是( )。

A.选择 B.循环 C.顺序 D.嵌套

【答案】D

【分析】在结构化程序设计中,任何复杂的程序都是由顺序、选择和循环三种基本结构组成的。

3.在文件名中与数据库表文件不相关的扩展名是( )。

A..fxp B..fpt C..idx D..cdx

【答案】A

【分析】.fxp是执行程序时自动编译生成的目标文件,与数据库表文件不相关;.fpt是数据库表文件的备注文件;.idx是数据库表文件的单项索引文件;.cdx是数据库表文件的复合索引文件。

4.要判断数值型变量X是否能被6整除,错误的条件表达式是( )。

A.MOD(X,6)=0 B.INT(X/6)=X/6 C.X%6=0 D.INT(X/6)=MOD(X,6)

【答案】D

【分析】MOD ( X,6 ) 是取模函数,得到的结果是X/6的余数,INT ( X/6 )是舍未取整函数,得到的结果是X/6的整数;X % 6是取模运算,得到的结果是X/6的余数。显然当X/6的余数为0时表示X能被6整数,或者当X/6取整的结果等于X/6时,也表示X能被6整数。

5.下列语句中不能出现LOOP和EXIT语句的程序结构是( )。

A.FOR-ENDFOR B.DO WHILE-ENDDO C.IF-ELSE-ENDIF D.SCAN-ENDSCAN

【答案】C

【分析】EXIT语句用于结束当前循环操作;LOOP语句用于中止本次循环,回到循环起始语句。所以LOOP和EXIT语句不能出现在分支结构IF-ELSE-ENDIF中。

6.在执行循环语句时,可利用下列( )语句跳出循环体。

A.LOOP B.SKIP C.EXIT D.END

【答案】C

【分析】EXIT语句用于结束当前循环操作,跳出所在的循环体。而LOOP语句的功能是回到循环起始;SKIP语句的功能是下移一条记录指针;没有单独的END命令。

7.由FOR I =1 TO 10 STEP-1 结构控制的循环将执行( )次。

A.10 B.1 C.出错 D.0

【答案】D

【分析】FOR-ENDFOR循环从循环变量的初值开始,重复执行循环体内的语句序列,直到循环变量的终值结束。但开始时要检查是否能进入循环,即检查循环初值、终值和步长,如果循环步长为负数,则循环初值要大于循环终值才能进入循环体。

8.由FOR I =1 TO 10结构控制的循环正常结束(不是中途退出)时,循环变量I的值为( )。

A.10 B.1 C.11 D.0

【答案】C

【分析】当正常结束FOR循环时,如果步长是正数,则循环变量I的值刚好大于循环变量终值,即退出循环后,循环变量I=循环变量终值+步长。

9.以下不属于循环控制结构的是( )。

A.DO WHILE-ENDDO B.WITH-ENDWITH C.FOR-ENDFOR C.SCAN-ENDSCAN

【答案】B

【分析】WITH-ENDWITH是面向对象程序设计中设置对象多个属性的结构,DO WHILE-ENDDO是条件循环结构,FOR-ENDFOR是循环次数确定的循环结构,SCANENDSCAN是实现表循环的循环结构。

10.在DO WHILE-ENDDO循环中,若循环条件设置为.T.,则下列说法正确的是( )。

A.程序无法跳出循环 B.程序不会出现死循环 C.用EXIT可跳出循环 D.用LOOP可跳出循环

【答案】C

【分析】这种循环一定要在循环体中使用EXIT语句,不然有可能是死循环。

11.以下程序之间的参数传递语句中,能够实现引用方式的是( )。

A.DO CH4-1 WITH A B.DO CH4-1 WITH (A) C.DO CH4-1 WITH A+B D.DO CH4-1 WITH 200

【答案】A

【分析】当WITH后的<实际参数列表>中是单个内存变量时,其值传给PARAMETERS中的对应参数后,在子程序中这些实际参数被隐含起来,但其值会随着对应参数值的变化而变化,这种传递方式称为引用。如果WITH后的<实际参数列表>是运算符连接的表达式或单个内存变量用圆括号括起来时,则值仅传给PARAMETERS中对应的形式参数,它们在子程序中不被隐含,这种传递方式称为传值。显然,如果WITH后带的是常量,也只能是传值。

12.设变量A,B已经被赋值,以下对自定义函数AREA (X,Y)的调用方法错误的是( )。

A.? AREA ( A,B ) B.DO AREA (A,B) C.M=AREA ( A,B) D.REPLACE Q WIYH AREA(A,B)

【答案】B

【分析】自定义函数虽然是一个子程序,但是不能用DO命令调用,而只能像系统函数一样用输出语句(?,??)输出或出现在表达式中。

13.用户在自定义函数或过程中接受参数,应使用( )命令。

A.PROCEDURE B.FUNCTION C.WITH D.PARAMETERS

【答案】D

【分析】PARAMETERS是接受参数语句。而PROCEDURE用于标识过程文件中的过程;FUNCTION用于标识自定义函数;WITH是DO命令中的短语项,带参数调用程序。

14.用户自定义的函数或过程可以存放在( )。

A.独立的程序文件或过程文件中 B.数据库文件中 C.数据表文件中 D.以上都可以

【答案】A

【分析】数据库文件和数据表文件用于存放原始数据,不能用于存放程序。程序应当存放在文件类型为.prg的独立程序文件或过程文件中。

15.在命令窗口赋值的内存变量默认的作用域是( )。

A.全局 B.局部 C.系统 D.不一定

【答案】B

【分析】在程序的一定范围内起作用的变量称为局部变量,在程序运行结束后,局部变量被释放。局部变量有3种属性,即自然属性、私有属性和本地属性,通过赋值、计算等语句得到的变量都是自然属性的局部变量。全局变量要用PUBLIC命令定义;系统内存变量是Visual FoxPro自动创建并维护的内存变量,用来保持系统固有信息。

4.3 程序填空题

阅读下列程序的说明及其程序,在每小题提供的若干可选答案中,挑选一个正确答案。

1.从键盘输入N个自然数(N由键盘输入确定),去掉一个最大数,去掉一个最小数,然后求平均值。

① SET TALK OFF
② CLEAR
③ INPUT "N=" TO N
④ INPUT "A=" TO A
⑤ STORE A TO X,Y
⑥ ---(1)---
⑦ P=N-2
⑧ ----(2)----
⑨    INPUT "B=" TO B
⑩    S=S+B
⑪    ---(3)----
⑫    X=B
⑬    ENDIF
⑭    -------(4)-----
⑮     Y=B
⑯    ENDIF
⑰ENDFOR
⑱----(5)----
⑲?R/P
⑳SET TALK ON

(1)A. S=A B.S=0 C.S=N D.I=1

(2)A.FOR I=1 TO N B.FOR I=2 TO N C.DO WHILE I<=N D.FOR I=1 TO A

(3)A.IF X<B B.IF X<Y C.IF Y>B D.IF Y<X

(4)A.IF X<B B.IF X<Y C.IF Y>B D.IF Y<X

(5)A.R=S B.R=S-A-B C.R=S-N-A D.R=S-X-Y

【答案】(1)A (2)B (3)A (4)C (5)D

【分析】对于程序填空的题目该如何着手呢?第一步一般是先按从里到外的顺序把程序的结构勾画出来(能用笔勾画更好);第二步找出程序的输入/输出变量和其他变量,知道每个变量的作用;第三步根据程序的功能推断出每个空格要填的语句。注意,填空时不一定要按顺序,有时某个空可能就是一个分支结构或循环结构的结尾,那就可以先填上。

为了便于分析说明,我们给本题的每个语句加了编号,同学们做的时候是不需要的。

本题中第11行与第13行可能是一对IF-ENDIF语句,第14行与第16行可能是一对IF-ENDIF语句,第8行与第17行可能是一对FOR-ENDFOR语句,为什么不是第6行与第17行呢?这是因为循环体中有一条语句S=S+B,而S又没有赋初值,赋初值一般在循环外面,所以第6行应该是给S赋初值。

接下来找程序的输入/输出变量和其他变量。输入变量为N和A,根据题目的功能,N是个数,A是第一次输入的自然数。输出是R/P,P=N-2,R前面还没有出现,应该在一个填空里。再看X,Y,是用于放所有数里的最大、最小数的,它们的初值是A。S放所有数的和。

空(1)给S赋初值,初值应该是A,即输入的第一个数要加进来。所以选答案A。

空(2)显然是FOR循环,要求输入N个数,已经输入一个数了,所以循环从2到N,选答案B。

空(3)是把输入的第二个数B与X比较,只有答案A是B与X比较,所以选A,从这个答案我们知道,X用于装最大数。即如果B大于X,B就把原来的X替换掉。

空(4)与空(3)类似,是把输入的第二个数B与Y比较,如果B小于Y,则替换。所以Y用于装最小数。选答案C。

空(5)显然是计算R,根据题目的要求:去掉一个最大数,去掉一个最小数,然后求平均值,所以R=S-X-Y。选答案D。

2.输入商品号,显示该商品号的所有销售记录;若用户输入空字符串或空格字符串,则系统要求用户重新输入;当用户输入字符串“000”时,则结束查询。

SET TALK OFF
USE 销售
----(1)---
ACCEPT "请输入商品号=" TO SPH
IF ----(2)---
  LOOP
ENDIF
IF ALLTRIM(SPH)="000"
  ---(3)---
ENDIF
LOCATE FOR 商品号=ALLTRIM(SPH)
IF FOUND( )
  DO WHILE !EOF( )
    DISPLAY
    ---(4)---
  ENDDO
ENDIF
ENDDO
USE
SET TALK ON

(1)A.DO WHILE T B.DO WHILE EOF( ) C.FOR I=1 TO RECCOUNT( ) D.DO WHILE .T.

(2)A.ALLTRIM(SPH)=0 B.LEN(STR(SPH))=0 C.LEN(ALLTRIM(SPH))=0 D.ALLTRIM(SPH)=“0”

(3)A.LOOP B.EXIT C.SKIP -1 D.SKIP 100

(4)A.CONTINUE B.SKIP C.SKIP -1 D.GO N

【答案】(1)D (2)C (3)B (4)A

【分析】 本题程序中有3对IF-ENDIF结构,它们是平行的关系,两对DO WHILE-ENDDO结构,是嵌套的关系。根据与ENDDO的配对关系,空(1)要填DO WHILE语句,循环条件是什么呢?根据题意:当用户输入字符串“000”时,则结束查询。输入其他数据则能反复查询,所以是一个永真循环,循环条件为.T.,空(1)选择答案D。

本题变量不多,只有变量SPH,用于存放输入的商品号。用DISPLAY命令输出满足条件的记录。空(2),若用户输入空字符串或空格字符串,则系统要求用户重新输入,怎样判断呢?如果该字符串去掉前后空格后长度为0,则输入的是空字符串或空格字符串。所以选答案C。空(3),是指当用户输入字符串“000”时,则结束查询,所以用EXIT退出循环,选答案B。空(4),在DO WHILE !EOF( )语句前有查找语句LOCATE FOR商品号=ALLTRIM(SPH),如果找到,则把所有满足条件的记录显示出来,只有CONTINUE语句才能配合LOCATE命令在表的剩余部分寻找其他满足条件的记录,所以选答案A。

3.显示指定表中的全部字段名,并由用户输入显示表信息的条件,最后列表显示满足条件的记录。

SET TALK OFF
CLEAR
DO WHILE .T.
  ACCEPT "请输入表名(扩展名略):" TO WJM
  IF -----(1)----
    USE (WJM)
  ELSE
    WAIT "指定的表不存在!" TIMEOUT 5
    LOOP
  ENDIF
  ?" 表中的全部字段名列表:"
  FOR N=1 TO ----(2)----
    ?FIELD(N)
  ----(3)---
  ACCEPT "请输入显示表信息的条件表达式:" TO EXPR
  ----(4)---
  WAIT "是否还要显示其他表文件中的内容?Y/N:" TO YN
  IF UPPER(YN)!="Y"
    ---(5)---
  ENDIF
ENDDO
USE
SET TALK ON

(1)A.FILE(WJM) B.FILE( ) C.FILE(&WJM) D.FILE(WJM+".DBF")

(2)A.5 B.FCOUNT( ) C.RECNO( ) D.RECCOUNT( )

(3)A.ENDDO B.ENDIF C.ENDFOR D.RETURN

(4)A.LIST FOR EXPR B.LIST FOR WJM C.DISPLAY FOR &EXPR D.DISPLAY ALL

(5)A.EXIT B.LOOP C.ENDIF D.ENDDO

【答案】(1)D (2)B (3)C (4)C (5)A

【分析】本程序是双循环嵌套结构,即永真循环里嵌套了一个FOR-ENDFOR循环,还嵌套了两个IF-ENDIF结构,两个IF-ENDIF结构是平行的关系。

FOR-ENDFOR用于显示表中的全部字段名,已知N的初值是1,那么终值则是表的字段数,即FCOUNT( ),所以空(2)选择答案B。另外FOR-ENDFOR循环缺ENDFOR,所以空(3)应该填ENDFOR,选择答案C。为什么不是空(4)填ENDFOR呢?因为此循环就是显示表中的全部字段名,循环体里已经有命令?FIELD(N)显示第N个字段名了,所以空(3)应该填ENDFOR。

程序的输入变量有WJM,EXPR和YN,它们分别存放输入的表名(不含扩展名)、输入的显示表信息的条件以及是否继续的标志。输出是指定表文件的字段名和满足条件的记录。再看空(1),IF的条件应该是若输入的文件存在,则打开文件,测试文件是否存在用函数FILE( ),而测试的字符串必须包含扩展名,所以空(1)填FILE (WJM+".DBF"),注意,变量WJM的内容才是表的名字,所以打开文件要用名函数,即USE (WJM)。

空(4)用于显示满足条件的记录,而条件是放在变量EXPR里的,应该把EXPR的内容作为显示的条件,所以要用到宏函数&或者值函数EVALUATE( ),这里答案是C。

空(5)是指当输入的继续标志YN不等于Y时,做什么?显然是退出,所以填EXIT。

4.程序的功能是:根据输入的正整数,计算不大于该数的所有奇数的累加和。

SET TALK OFF
CLEAR
YN="Y"
DO WHILE UPPER(YN)="Y"
  INPUT "请输入两位以内的正整数:" TO N
  STORE 0 TO X,Y
  Z="0"
  DO WHILE X<N
    X=X+1
    IF INT(X/2)=----(1)----
      ----(2)----
    ELSE
      Z=Z+"+"+STR(X,2)
      ----(3)----
    ENDIF
  ENDDO
  ? "&Z="+STR(Y,4)
  WAIT "继续计算?(Y/N)" TO YN
ENDDO
SET TALK ON

(1)A.X B.X/2 C.N/2 D.N

(2)A.EXIT B.Y=Y+X C.LOOP D.N=N-1

(3)A.Y=Y+2 B.LOOP C.EXIT D.Y=Y+X

【答案】(1)B (2)C (3)D

【分析】本程序是两个DO WHILE-ENDDO的循环嵌套结构,内循环中还用了IF-ENDIF结构判定奇偶数。外循环根据用户的选择继续或退出。

程序的输入变量有N和YN,分别存放输入的正整数和是否继续的标志。输出变量有Z和Y,分别是所有奇数构成的字符串和所有奇数的累加和。还有循环变量X,从1变化到N。

先看空(1),用于判定X是否是偶数,所以填X/2。空(2)是指在X为偶数时做什么?根据题目的意思,偶数不做处理,所以结束本次循环,处理下一个X,所以填LOOP。空(3)是进行奇数的累加,我们已经知道输出有Z和Y,而Y只赋了初值0,没有进行累加,所以本空对奇数进行累加,填Y=Y+X。

5.计算整数3~M中有多少个素数(只能被1或自身整除的奇数自然数称为素数)。

SET TALK OFF
CLEAR
INPUT "M=" TO M
S=0
---(1)---
  IF SS(I)
    S=S+1
    ??STR(I,5)
  ENDIF
ENDFOR
?STR(S,5)
SET TALK ON
FUNCTION SS
----(2)---
FOR J=2 TO X-1
  ---- (3)----
   EXIT
  ENDIF
ENDFOR
IF J=X
RETU .T.
ELSE
 ----(4)---
ENDIF
ENDFUNCTION

(1)A.FOR I=3 TO M-1 B.FOR I=M TO 3 STEP -1 C.DO WHILE I<=M D.FOR I=3 TO INT(M/2)

(2)A.X=I B.PUBLIC X C.PRIVATE X D.PARAMETERS X

(3)A.IF INT(X/J)=X/J B.IF INT(X/J) C.IF X%J=X/J D.IF J%X=0

(4)A.RETURN B.RETURN .F.C.QUIT D.RETURN X

【答案】(1)B (2)D (3)A (4)B

【分析】本程序前面一段是主程序(SET TALK OFF~SET TALK ON),后面一段是一个自定义函数(FUNCTION SS~ENDFUNCTION),自定义函数的名称为SS。主程序是FOR循环里套了一个IF分支,用于逐个检查3~M中有多少个素数,自定义函数有一个FOR循环,里面套了一个IF分支,循环外还有一个分支,用于判定给定的参数是否是素数,如果是素数则函数结果为.T.,如果不是素数则函数结果为.F.。那么怎样知道X是否是素数呢?就是根据素数定义,用2到X-1去除X,只要有一个数能整除X,就退出循环,X不是素数。只有当没有一个数能整除X时,X才是素数。

输入变量是M,指定要检查数据的上限。输出变量S,存放素数的个数,循环控制变量I,控制主程序循环的次数,如果I是素数则输出I。X变量是自定义函数接受的参数,J是自定义函数中的循环控制变量,J从2变化到X-1,逐个去除X。

先看空(1),因为下面有一个ENDFOR语句,故要填FOR语句,根据题意:计算3~M中有多少个素数,循环变量是从3至M,包括M,所以选择答案B。

空(2),根据自定义函数的结构,如果有参数,那么程序的第一个语句应该是接受参数,通过下面的程序,知道接受的参数是X,所以选答案D。

空(3),是自定义函数的返回结果,一种情况是J=X,表示每次循环都做过,没有整除,X是素数,返回结果.T.;另一种情况则为.F.,所以选答案B。

空(4),是一个X能否被J整除的判断,所以选答案A。

4.4 程序阅读题

1.写出运行结果

SET TALK OFF
CLEAR
ACCEPT "请输入表名:" TO FNAME &&输入:职工
USE (FNAME)
ZDSM=FCOUNT( )
FOR I=1 TO ZDSM
   ?FIELD(I)
ENDFOR
SET TALK ON

【分析】

对于程序阅读题目,我们也建议先观察程序的结构,然后找出输入、输出变量,知道每个变量的大致作用。再按照程序运行的顺序进行阅读,把输入的数据代入变量中,阅读过程中可以适当做些标记,例如标记关键语句的功能、当前变量的值等。

本程序要清楚几个关键点,一是USE (FNAME)表明打开指定的表文件;二是FCOUNT( )函数返回的是表中字段的个数,决定了循环的次数;三是FIELD(I)函数返回的是第I个字段的名称。

【答案】

2.写出运行结果

SET TALK OFF
CLEAR
X=.T.
Y=0
DO WHILE X
   Y=Y+1
   IF INT(Y/7)=Y/7
      ??Y
   ELSE
      LOOP
   ENDIF
   IF Y>15
      X=.F.
   ENDIF
ENDDO
SET TALK ON

【分析】

本题X的初值为.T.,所以DO WHILE是一个永真循环,Y的初值为零,在循环体内不断加1,只有当Y的值能被7整除时才输出,不能被7整除则继续加1,且不去判断Y是否大于15。什么时候退出循环呢?只有出现第1个大于15且能被7整除的Y后,使X置.F.,才退出循环体。这里要注意LOOP的位置和作用。

【答案】

7 14 21

3.设输入的字符串P为"AHCHLIG"。

SET TALK OFF
CLEAR
ACCEPT "P=" TO P &&
L=LEN(P)
C="!"-"!"
FOR I=1 TO L
  ZF=SUBSTR(P,I,1)
  IF ZF>="A" AND ZF<="T"
    ZF=CHR(ASC(ZF)+6)
  ENDIF
  C=ZF+C
ENDFOR
?C
SET TALK ON

【分析】

将键盘输入的字符串赋给P,L记录字符串的长度,循环从第1个位置起依次截取P的一个字符,如果该字符在"A"到"T"之间,则取该字符后移6个位置的字符,即将该字符的ASCII码加6(如果截取的字符是"A",其ASCII码65加6则为71,即字符"G")再转换成字符,并将该字符从左边连接到C串上。

【答案】

MORNING!!

4.设输入的数值N为5。

SET TALK OFF
CLEAR
INPUT "N=" TO N
P=N
I=1
DO WHILE N>0
   ?SPACE(I)
   P=N+I
   DO WHILE P>0
     ??"*"
     P=P-1
   ENDDO
   I=I+1
   N=N-1
ENDDO
SET TALK ON

【分析】

本题目是双重循环,用来实现二维图形的输出,外循环N次,控制图形的行数、起始输出位置及换行,内循环控制在同一行上输出的“*”个数。

【答案】

5.变量X的输入值为36。

SET TALK OFF
CLEAR
INPUT "X=" TO X
S=STR(X,5)+"="
FOR I=2 TO X
   IF MOD(X,I)=0
     S=S+STR(I,3)+"*"
     X=INT(X/I)
     =I-1
   ENDIF
ENDFOR
?LEFT(S,LEN(S)-1)
SET TALK ON

【分析】

键盘输入X值,循环变量I从2至X逐个变化,如果X能被I整除(即I是X的因子),则将该数转换成字符后连接到S字符串上,同时将X/I后取整等待新的X,I-1是为了继续判断原来的I(FOR没有加1时的I)是否为新的X因子,循环处理,直到将X的所有因子边乘式连接到S字符串中。输出语句?LEFT(S,LEN(S)-1)中的LEN(S)-1是为了将最后一个乘号“*”去掉。

【答案】

36=2*2*3*3

6.设输入的数值N为5。

SET TALK OFF
CLEAR
INPUT "N=" TO N
FOR I=1 TO 2*N-1
   IF I<=N
      ?SPACE(20)
      FOR J=1 TO 2*(N-I+1)-1
         --CHR(64+N-I+1)
      ENDFOR
   ELSE
      ?SPACE(20-2*(I-N))
      FOR J=1 TO 2*(I-N)+1
         ??CHR(65+I-N)
      ENDFOR
  ENDIF
ENDFOR
SET TALK ON

【分析】

本题目是双重循环,用来实现二维图形的输出,外循环2*N-1次,控制图形的行数、起始输出位置及换行,内循环控制在同一行上输出的字符个数。内循环根据I≤N还是I>N分两种情况处理每行字符的输出。

【答案】

7.写出运行结果。

SET TALK OFF
CLEAR
USE 销售
? '----------------------------'
? '职工号 金额'
GO TOP
DO WHILE.NOT.EOF( )
  IF 金额<1000
    ? 职工号+SPACE(5)+STR(金额,7,2)
  ENDIF
  SKIP
ENDDO
? '----------------------------'
USE
SET TALK ON

【分析】

本题目是一个对销售表的循环,如果金额<1000,则输出职工号和金额。

【答案】

8.设输入的数值N为6,M为8,写出运行结果。

SET TALK OFF
CLEAR
INPUT 'N=' TO N &&输入6
INPUT 'M=' TO M &&输入8
X=MIN(N,M)
FOR I=X TO 1 STEP -1
  IF M/I=INT(M/I) AND N/I=INT(N/I)
    GYS=I
    EXIT
  ENDIF
ENDFOR
? GYS,M*N/GYS
SET TALK ON

【分析】

本题目是一个FOR循环结构,如果I能同时整除M和N,则I是M、N的公因数,并把这个公因数I赋值给GYS,退出循环。最后输出GYS和M*N/GYS。

【答案】

2.00 24.00

9.写出运行结果。

SET TALK OFF
CLEAR
X=3
Y=5
S=AREA(X,Y)
?S
SET TALK ON
FUNCTION AREA
PARA A,B
S1=A*B
RETURN S1

【分析】

本题目前半段(SET TALK OFF~SET TALK ON)是一个主程序,后半段(FUNCTION AREA到RETURN S1)是一个自定义函数,函数名为AREA。把X,Y带给函数AREA对应的变量A,B,计算A*B,结果再赋值给S。

【答案】

15

4.5 程序设计题

1.输入边长,计算并输出正方形的周长、面积和体积。

【分析】

本题是一个简单的顺序结构,输入一个变量——边长,按公式计算并输出即可。

【参考程序】

SET TALK OFF
CLEAR
INPUT "正方形边长N=" TO N
?" 正方形周长为:",4*N
?" 正方形面积为:",N*N
?" 正方形体积为:",N*N*N
SET TALK ON

2.某航空公司规定:如果订票数超过10张,则票价优惠15%;如果订票数超过20张,则票价优惠25%。输入票价和定票数,计算并显示金额。

【分析】

本题是一个三分支的结构,按订票数分3种情况。程序可以用两个IF-ENDIF嵌套实现,也可以用一个DO CASE-ENDCASE语句实现。

【参考程序】

SET TALK OFF
CLEAR
INPUT "请输入票价: " TO PJ
INPUT "请输入定票数:" TO DPS
DO CASE
    CASE DPS>20
      JE=DPS*PJ*.75
    CASE DPS>10
      JE=DPS*PJ*.85
    OTHERWISE
      JE=DPS*PJ
ENDCASE
?"总金额为:",JE
SET TALK ON

3.编写程序,找出满足以下条件的3位自然数:百位数和十位数组成的2位自然数是一个完全平方数,且百位数大于十位数,例如,自然数819就满足上述条件,81是一个完全平方数,且8大于1。

【分析】

本题必须在所有3位自然数之间找,循环变量从100~999。把这个数除以100取整,可以得到百位数;这个数除以100的余数再除以10取整,可以得到十位数;把这个数除以10取整则得到百位数和十位数组成的两位自然数。若取出来的数满足题目的条件就把该数输出,见方法1。百位、十位等数字的取得也可以用字符串的截取方式实现,见方法2。

【参考程序】

方法1:

SET TALK OFF
CLEAR
FOR I=100 TO 999
    A1=INT(I/100) &&取出百位数
    A2=INT(MOD(I,100)/10) &&取出十位数
    A3=INT(I/10) &&取出百位与十位的组合
    IF A1>A2 AND SQRT(A3)=INT(SQRT(A3))
        ??I
    ENDIF
ENDFOR
SET TALK ON

方法2:

SET TALK OFF
CLEAR
FOR I=100 TO 999
    X=STR(I,3) &&将I转换为字符数字赋给X
    A1=VAL(SUBSTR(X,1,1)) &&截取出百位数
    A2=VAL(SUBSTR(X,2,1)) &&截取出十位数
    A3=VAL(SUBSTR(X,1,2)) &&截取出百位与十位的组合
    IF A1>A2 AND SQRT(A3)=INT(SQRT(A3))
        ??I
    ENDIF
ENDFOR
SET TALK ON

4.编写程序,计算算式:S=1/1*2+1/2*3+…+1/N*(N+1)

【分析】

本题是一个多项式的累加求和,采用FOR-ENDFOR循环结构实现最简单,循环变量从1到N。N由用户确定,所以从键盘输入;用S存放累加和,在循环外赋初值0。用中间变量T放每一项的值,循环结束输出累加和S。

【参考程序】

SET TALK OFF
CLEAR
INPUT "请输入自然数N=" TO N
S=0
FOR I=1 TO N
   T=1/(I*(I+1))
S=S+T
ENDFOR
?S
SET TALK ON

5.编写程序,计算算式:S=11+22+33+44+55+…+NN

【分析】

本题是一个多项式的累加求和,采用FOR-ENDFOR循环结构实现,循环变量从1~N。N由用户确定,从键盘输入;用S存放累加和,在循环外赋初值0。用中间变量T放每一项的值,由于每项数据是一个累乘,所以再用一个FOR-ENDFOR循环。

【参考程序】

SET TALK OFF
CLEAR
INPUT "请输入自然数N=" TO N
S=0
FOR I=1 TO N &&累加的项数
   T=1 &&每项值的初值
   FOR J=1 TO I &&每项累乘的次数
     T=T*I
   ENDFOR
   S=S+T &&把累乘结果加给S
ENDFOR
?S
SET TALK ON

6.整数1用了一个数字,整数10用了1和0两个数字。编写程序计算,从整数1~1000一共要用多少个数字1和多少个数字0。

【分析】

本题要从整数1检查到整数1000,所以用FOR-ENDFOR循环实现,循环变量从1~1000。用变量S1和S2分别存放1和0的个数。由于对于每个数需要检查每位数中是否有1或 0,所以还需要套用一个循环逐个取数字,直到该数为0结束。逐个取数字用取余函数MOD(M,10)实现,即取出M最右边的一位数,判定是否等于1或0,若等于1,则S1加1;若等于 0,则S2加1。取出最右边的一位数后剩下的数则是INT(M/10),把INT(M/10)赋值给M,检查M是否大于0,若大于0则继续,直到等于0,结束内循环。

【参考程序】

SET TALK OFF
CLEAR
STORE 0 TO S1,S2
FOR I=1 TO 1000
    M=I
    DO WHILE M>0
        L=MOD(M,10) &&取出M最右边的一位数
        IF L=1
            S1=S1+1 &&S1存放1的个数
        ENDIF
        IF L=0
            S2=S2+1 &&S21存放0的个数
        ENDIF
        M=INT(M/10) &&取出最右边的一位数后剩下的数
    ENDDO
ENDFOR
?"1的个数为:",S1
?"0的个数为:",S2
SET TALK ON

7.搬砖:36块砖,36人搬,男搬4块,女搬3块,两个小孩抬1块,要求一次搬完。问:需要男、女、小孩各多少人。

【分析】

假设男、女、小孩各需要X,Y,Z人。如果全部让男人搬,则最多需要9人;如果全部让女人搬,则最多需要12人。由此我们知道X的取值范围是0~9,Y的取值范围是0~12。如果X,Y能确定,根据题目的要求,人数一共是36人,那么Z就等于36-X-Y。什么样的X,Y,Z符合要求呢?就是当X,Y,Z搬砖的总数等于36时,它们才符合题目的要求。所以本题可以用穷举法,让X从0变到9,Y从0变到12,然后根据公式Z=36-X-Y算出Z。如果满足条件4*X+3*Y+0.5*Z=36,即输出X,Y,Z。所以本题是两个FOR-ENDFOR的双循环结构。

【参考程序】

SET TALK OFF
CLEAR
FOR X=0 TO 9
   FOR Y=0 TO 12
       Z=36-X-Y
       IF 4*X+3*Y+Z/2=36
         ?"男人="+STR(X,2),"女人="+STR(Y,2),"小孩="+STR(Z,2)
       ENDIF
   ENDFOR
ENDFOR
SET TALK ON

8.统计显示“销售”表中所有销售员的销售情况。输出格式如图1-1所示。

图1-1 显示销售情况

【分析】

由于“销售”表中所有的职工都是混放在一起的,要解决这个问题,首先必须利用索引将相同的职工排列在一起,用外循环使表的所有记录参与统计,用内循环输出某一职工的销售明细。出现一个新职工时才需要输出职工号,所以在内循环外的输出语句中有职工号。

【参考程序】

SET TALK OFF
CLEAR
USE 销售
?"职工号 商品号 销售数量"
?"*******************************"
INDEX ON 职工号 TO IZGH
DO WHILE !EOF( )
  ZGH=职工号
  ?职工号+SPACE(6)+商品号+STR(数量,10)
  SKIP
  DO WHILE ZGH=职工号
    ?SPACE(12)+商品号+STR(数量,10)
    SKIP
  ENDDO
ENDDO
USE
SET TALK ON

9.编写一个自定义函数,判断一个数是否能同时被5与38整除。并显示1~1000之间所有能同时被5与38整除的数。

【分析】

本题先编一个自定义函数,判断接收的一个数是否能同时被5与38整除,是,返回.T.;否,返回.F.。然后设计主程序显示1~1000之间所有能同时被5与38整除的数,判断处理直接调用自定义函数。所以把自定义函数放在主程序的后面。

【参考程序】

SET TALK OFF
CLEAR
FOR I=1 TO 1000
    IF SS(I) &&如果函数SS返回.T.,则满足条件,显示I
        ?I
    ENDIF
ENDFOR
SET TALK ON
FUNCTION SS &&自定义函数SS
PARAMETERS X
IF MOD(X,5)=0 AND MOD(X,38)=0
    RETU .T.
ELSE
    RETU .F.
ENDIF
ENDFUNC