资源描述
单击此处编辑母版标题样式,单击此处编辑母版文本样式,第二级,第三级,第四级,第五级,*,6.9 顺序结构程序设计,一、,顺序结构:根据程序中语句的书写顺序依次逐条执行。流程图如下:,语句1,语句2,例6.1查找某个学生信息(lz1),Open database 教学管理,Use 学生,Accept “请输入学生姓名:” to name,Locate for 姓名=name,Display,Use,return,分类:,简单分支语句(IFENDIF),选择分支语句(IFELSEENDIF),结构分支(do case-endcase,6.10 分支结构,1简单分支语句(Lz1),格式:IF ,ENDIF,IF,.T.,条件?,语句块,ENDIF,.F.,单向IF语句流程图,功能:计算条件表达式的值,若为真(.T.),则执行语句块中的语句;若为假(.F.),不执行语句块。无论执行还是不执行,程序都将转向ENDIF下一条语句继续执行。,说明:,(1) IF 和 ENDIF必须配对出现,且分两行书写。,(2) 条件表达式可以是关系表达式或逻辑表达式。,例6.2,Open database 教学管理(lz2),Use 学生,Accept “请输入学生姓名:” to name,Locate for 姓名=name,If found(),Display,Endif,?“结束”,Use,return,例6.3,Use zgda(lz3),Locate for 基本工资50公斤,Set talk off,Input “请输入行李的重量为:” to w,If w2.5,PAY=(X-2.5)*1.2+6,ELSE,PAY=6,ENDIF,? 应付费,ROUND(PAY,0), 元,CANCEL,例6.5 在学生信息.DBF中查找某人,若找到,显示该记录;若找不到,显示“查无此人!”。(lz6),* PROG7.PRG,SET TALK OFF,USE 学生,ACCEPT 输入待查找人的姓名: TO NAME,LOCATE FOR 姓名=NAME,IF FOUND(),DISP,ELSE,? 查无此人! ,ENDIF,USE,SET TALK ON,CANCEL,有学生成绩表:现要统计60分以下有多少人,60到69分的有多少人,70-89分的有多少人,90分以上的有多少人。,3 IF语句的嵌套,IF-ELSE-ENDIF语句中的语句块里可以包含任何合法的语句,也可以包含另一条IF语句,这就构成了IF语句的嵌套。嵌套IF语句可以解决一入口,三,分支,甚至更多,分支,的问题。嵌套形式可以是多种多样的,以下是其中的一种,:,IF ,ELSE,IF ,ELSE,ENDIF,ENDIF,语句块3,.F.,ELSE,条件2,语句块2,条件1,语句块1,IF,.T.,.F.,ELSE,IF,.T.,END IF,If 大学英语=90,a=a+1,Else,If 大学英语=70,b=b+1,else,If 大学英语=60,c=c+1,else,d=d+1,endif,Endif,endif,If 大学英语60,d=d+1,Else,If 大学英语70,b=b+1,else,If 大学英语60,d=d+1,Else,If 大学英语70,c=c+1,else,If 大学英语90,b=b+1,else,a=a+1,endif,Endif,endif,这样可以不可以?,4结构分支语句,格式:,DO CASE,CASE ,CASE ,CASE ,OTHERWISE,ENDCASE,条件1,条件2,条件n-1,语句块n,语句块1,语句块n-1,DO CASE,ENDCASE,OTHERWISE,语句块2,.T.,.T.,.F.,.F.,.F.,.T.,功能:依次检测条件表达式的值,一旦某一条件满足,执行相应语句块,然后转到ENDCASE下一条语句。如果所有条件表达式的值都为假,倘若无OTHERWISE子句,则不执行任何语句,直接转到ENDCASE下一条语句;如若有OTHERWISE子句,则无条件执行OTHERWISE与ENDCASE之间的语句块,然后转到ENDCASE下一条语句。,说明:,(1)如果有两个或两个以上的条件为真,则只执行第一个条件表达式为真的CASE后的语句组,之后即转去执行ENDCASE之后的语句而不会再去判断下一个CASE中的条件。,Do case,case,大学英语=90,a=a+1,case,大学英语=70.and.大学英语=60,c=c+1,otherwise,d=d+1,endcase,也可以这样做,Do case,case,大学英语60,d=d+1,case,大学英语70,c=c+1,case,大学英语=60,a=a+1,case 大学英语=70,b=b+1,case 大学英语=90,c=c+1,otherwise,d=d+1,emdcase,结果是什么?,1当型循环语句,格式:DO WHILE ,ENDDO,6.11 循环结构,初始设置,条件满足吗?,循环体语句,LOOP,EXIT,.F.,.T.,DO WHILE,ENDDO,功能:当的值为真(.T.)时,执行循环体中的语句,一旦的值为假(.F.),程序跳出循环体,转到ENDDO下一条语句继续执行。,说明:,(1)如果条件永远成立,形成死循环。为了避免死循环,在循环体中必须要有语句能够改变条件表达式的值。,(2)当循环次数事先未知时,使用DO WHILE-ENDDO语句。,(3)循环体中,可以出现LOOP语句。遇到LOOP语句时,程序立即转向DO WHILE循环起始语句,而不再执行LOOP下面的循环体语句。,(4) 循环体中,可以出现EXIT语句。遇到EXIT语句时,程序立即跳出本层循环,转向逻辑上的下一条语句继续执行。设置EXIT语句,也是防止死循环的一种方法。,DO WHILE 语句的流程图,例6.11,Clear LZ7,use 学生成绩,store 0 to a,b,c,d,do while .not.eof(),Do case,case 大学英语=90,a=a+1,case 大学英语=70,b=b+1,case 大学英语=60,c=c+1,otherwise,d=d+1,endcase,skip,enddo,?a,b,c,d,STORE 0 TO C, W (LZ8)(用IF语句改写),USE ZGDA,DO WHILE .NOT.EOF( ),DO CASE,CASE (年龄45).AND.职称=讲师,W=W+1,CASE (年龄45) .AND.职称=副教授,C=C+1,ENDCASE,SKIP,ENDDO,? “45岁以下的讲师人数为: ,W,? “45岁以下的副教授人数为: ,C,SET TALK ON,CANCEL,例6.12统计职工表中,职称是”讲师”和副教授,年龄在45岁以下的教师人数.,例6.3 求N!=123N(lzn),input n= to n,s=1,i=1,do while i=1979-01-01,DISP,N=N+1 & 记数器,ENDIF,SKIP & 修改记录指针,漏写该句,程序死循环,ENDDO,? 1979年以后出生的人数为+STR(N,2)+ 人,USE,SET TALK ON,CANCEL,例6.15 完善例6.7,使程序能多次查找学生的记录,一旦输入N,立即结束查找。lz9,USE 学生,x=Y,DO WHILE UPPER(x)= Y,ACCEPT 输入待查找学生的姓名: TO NAME,LOCATE FOR 姓名=NAME,IF .NOT. EOF(),DISP,ELSE,? 查无此人! ,ENDIF,WAIT 是否继续查找(Y/N)? TO x,ENDDO,? 结束查找,USE,CANCEL,例6.16 键盘输入两个整数,求它们的最大公约数和最小公倍数。(lz12),INPUT 输入一个整数: TO M,INPUT 输入另一个整数: TO N,M1=M,N1=N,T=MOD(M,N),DO WHILE T#0,M=N,N=T,T=MOD(M,N),ENDDO,? 最大公约数为: ,STR(N,4),? 最小公倍数为: , STR(M1*N1/N,4),CANCEL,辗转相减求两个自然数m,n的最大公约数.lz12a,m=m-n mn,n=n-m nm,m,n 为公约数 m=n,1.转跳语句(LOOP),在DO WHILEENDDO循环体内提供了一条短路语句,可以起到转跳作用,语句格式:,Do while ,if ,LOOP,endif,enddo,语句功能:,中断本次循环体的执行,跳回到DO WHILE的开始处,重复条件的判断.但要注意具有多重循环的程序中,只返回到与它本身所处的本层循环体相匹配的DO WHILE语句.,Do while ,Do while ,if ,LOOP,endif,enddo,loop,Enddo,【例6.17】,工资小于160元的增加10元,SET TALK OFF,USE DA2,DO WHILE .NOT.EOF( ),if 工资=160,SKIP,LOOP,ENDIF,REPLACE 工资 WITH 工资10,SKIP,ENDDO,【例6.18】lz10,求0100之间奇数之和,SET TALK OFF,X=0,Y=0,DO WHILE X100,EXIT,ENDIF,S=S+N,N=N+1,ENDDO,? “S=”,S,2FOR-EndFor循环语句,格式:FOR = TO STEP ,ENDFOR,循环变量超过终值?,FOR,循环变量=初值,循环体,LOOP,EXIT,循环变量+步长,ENDFOR,.T.,.F.,记数型循环语句流程图,功能:语句执行时,首先循环变量赋以初值,与终值比较,若超过终值,则循环体一次也不执行,直接跳到循环终止语句ENDFOR的下一条语句;若不超过终值,则依次执行循环体语句,遇到ENDFOR后,程序转回到FOR循环初始语句。然后循环变量加上步长,再判断是否超过终值,只要不超过终值就执行循环体。一旦超过终值,程序退出循环体,继续执行ENDFOR的下一条语句。,说明:,(1)步长可正可负。若步长为1,可以省略STEP子句。,(2)计数型循环语句用于循环次数事先已知的场合。循环次数可按下式来计算:,INT(ABS(终值-初值)/步长)+1,(3)循环体内可以出现 LOOP和EXIT语句,其功能如前所述。,(4)循环结束语句一般用ENDFOR,,例6.20,找出表中年龄最大的记录(lz13),SET TALK OFF,USE ZGDA,MAX=年龄,J=RECCOUNT() 指表中所含的记录的总数,FOR I=2 TO J,SKIP,IF MAX=1979-01-01,DISP,N=N+1,ENDSCAN,? 1979年以后出生的人数为+STR(N,2)+ 人,USE,SET TALK ON,CANCEL,例6.24在教学管理.DBC中有数据库表学生成绩.DBF,计算学生的总分,并按如下规定填写等级字段:lz15,总分=250 为“优秀” 210总分249为“良好”,180总分209为“一般” 总分=250,REPL 等级 WITH 优秀,CASE 总分=210 & 不必写成:总分=210 AND 总分=180,REPL 等级 WITH 一般,OTHERWISE,REPL 等级 WITH 差,ENDCASE,ENDSCAN,LIST,CLOSE DATABASE,CANCEL,USE 学生成绩,REPL ALL 总分 WITH 数学+大学英语+语文,go top,do while .not.eof(),DO CASE,CASE 总分=250,REPL 等级 WITH 优秀,CASE 总分=210 & 不必写成:总分=210 AND 总分=180,REPL 等级 WITH 一般,OTHERWISE,REPL 等级 WITH 差,ENDCASE,skip,enddo,LIST,CANCEL,4循环的嵌套,如果单层循环里的循环体中又包含另一层循环,即循环内套循环,就构成了二重循环。同理,还有三重循环或更多重循环。三种形式的循环可以互相嵌套,但既然嵌套,必须是完全嵌套,不能交叉嵌套。,Do while ,语句1,do while ,语句2.,enddo,语句3.,Enddo,例6.21 打印如图所示的图形,* PROG21.PRG,FOR I=1 TO 4 & 打印4行,FOR J=1 TO 5 & 每行打印5个字符,? *,ENDFOR,?,ENDFOR,显示结果如下: *,*,*,*,例6.22 打印图形,* PROG22.PRG,FOR I=1 TO 5 & 打印5行,FOR J=1 TO I & 每行打印字符数与I有关,? *,ENDFOR,?,ENDFOR,运行结果如下:,*,*,*,*,*,例6.23 打印图形lz16,* PROG23.PRG,FOR I=5 TO 1 STEP 1 & 打印5行,STEP用负值,FOR J=1 TO I,? *,ENDFOR,?,ENDFOR,?,CANCEL,结果如下: *,*,*,*,*,例6.24 打印图形lz17,* PROG24.PRG,FOR I=1 TO 5 & 打印5行,?SPACE(5-I),FOR J=1 TO 2*I-1 & 随I改变,打印1,3,5,7,9列,? *,ENDFOR,?,ENDFOR,结果如下: *,*,*,*,*,clear,FOR I=1 TO 5,? SPACE(20-i),FOR J=1 TO i*2-1,? *,ENDFOR,ENDFOR,例6.25 打印图形,* PROG25.PRG,FOR I=5 TO 1 STEP 1 & 打印倒三角,STEP为负值,? SPACE(5-I) & 换行效果与例6.24相同,FOR J=1 TO 2*I-1,? *,ENDFOR,ENDFOR,结果如下: *,*,*,*,*,clear,FOR I=1 TO 5,? SPACE(20+i),FOR J=1 TO (5-i)*2+1,? *,ENDFOR,ENDFOR,clear,input n= to n,FOR I=1 TO n,? SPACE(50+I),FOR J=1 TO 2*n-2*i+1,? *,ENDFOR,ENDFOR,例6.26 打印图形,* PROG26.PRG,FOR I=1 TO 5 & 打印前5行,? SPACE(10-I) & 使图形向右移5列,FOR J=1 TO 2*I-1 & 打印呈三角形,?CHR(64+I) & 打印大写字母,ENDFOR,ENDFOR,FOR I=4 TO 1 STEP 1 & 打印后4行,?SPACE(10-I) & 先换行,再输出,FOR J=1 TO 2*I-1,?CHR(64+I),ENDFOR,ENDFOR,结果如下:,A,BBB,CCCCC,DDDDDDD,EEEEEEEEE,DDDDDDD,CCCCC,BBB,A,例6.27 打印九九乘法表lz18 lz9,?SPACE(4)+ * & 输出第一行,FOR I=1 TO 9,?STR(I,5),ENDFOR,?,FOR I=1 TO 50 & 输出一条由50个“-”组成的直线,?“-”,ENDFOR,?,FOR A=1 TO 9,?STR(A,5),FOR B=1 TO A,?STR(A*B,5),ENDFOR,?,ENDFOR,CANCEL,数组,一、数组:,名字相同、用下标区分的内存变量称为数组。,二、数组的定义,数组名的取法和一般的变量名取法相同,数组名和简单变量不能同名.,定义数组命令:,DIMENSION ,),(,命令功能:定义一个或多个内存变量数组。,说明:,最多可有3600个元素,显示内存时只算一个变量,数组下标起始值是1,数组元素隐含的逻辑值为“假”,*二维数组,可用一维下标来存取。这是由于在内存中,二维数组元素是按行列次序排列,它们每个元素都可看作单独一个内存变量使用,,主要有以下特点:,(1)数组元素的类型,由所赋的值来决定,(2)数组变量可以不带下标使用,在赋值语句的右边,表示该数组第一个元素,在赋值语句的左边,表示该数组所有元素,(3)数组和数据表之间可相互转换,即数据表中数据可以转换为数组数据,数组数据也可以转换为数据表中的数据,数组实例,DIMENSION a(2,3),? A4,? A(2,1),? A6,? A(2,3),A(1,1) A(1,2) A(1,3),1,2 3,A(2,1) A(2,2) A(2,3),4 5 6,数组实例,DIMENSION a(2,3),二、数组的赋值,格式:,STORE 表达式 TO 数组名,数组名=表达式,命令功能:,将表达式的值赋给数组变量,上述两个命令是完全等价的,给数组赋值还可用ACCEPT、INPUT、WAIT语句,Dime s(3,5)lz23,For i= 1 to 3,For j=1 to 5,Input “第”+str(I,1)+”行第”+str(j,1)+”个元素” to s(I,j),Endfor,Endfor,For i= 1 to 3,For j=1 to 5,?s(I,j),Endfor,?,Endfor,clear,dime a(10),for i= 1 to 10,a(i)=int(rand()*20)+1,?a(i),endfor,max=a(1),imax=1,for i=2 to 10,if a(i)max,max=a(i),imax=i,endif,endfor,?max,imax,产生10个1-20之间的随机数,找出其中最大的数lz24,2,4,6,8,10,1,3,5,7,9,9,7,5,3,1,10,8,6,4,2,交换前,交换后,For i=1 to int(10/2),T=a(i),A(i)=a(10-i+1),A(10-i+1)=t,Endfor,For i=1 to 10,?a(i),Endfor,lz25,表与数组之间交换数据,1.当前记录复制到数组,命令格式:,Scatter to fields,将表中当前记录复制到指定的数组.,在复制时,第一个字段值传送给第一个数组元素,第二个字段值传给第二个数组元素,依次类推.如果没有数组 ,则自动创建数组,如果已创建的数组元素个数比字段个数多,则多余的数组元素保持原值;如果已创建的数组元素个数比字段个数少,则自动扩展数组,使得数组元素个数与字段个数相等.,2.数组内容复制到当前记录,命令格式:,Gather from fields ,将数组中的数据复制到当前记录.,第一个数组元素复制到第一个字段,第二个数组元素复制到第二个字段,依次类推,各个数组元素与对应字段的数据类型必须一致.如果数组元素个数比字段个数少,多出的字段保持原值,如果数组元素个数比字段个数多,多出的数组元素不复制.,两条记录换位置,use 学生lz20,list,dimension a(1),b(1),x=Y,do while upper(x)=Y,input 第一条记录 to m,input 第二条记录 to n,go m,scatter to a,go n,scatter to b,gather from a,go m,gather from b,wait 继续吗(Y/N?) to x,enddo,例:现有数据库DD.DBF,其结构如下:订单号 N(3,0),客户号 C(3),签单日期 D,金额 N(6,2)。数据库TJ2.DBF 结构如下:月份 N(2,0),数量 N(2,0),总金额 N(8,2),编程序统计出各个月份所签订单的数量及其总金额,并将结果按月份的升序放在库文件TJ2.DBF。(vf5),set talk off,dime a(12,2),a=0,use dd,do while .not. eof(),a(month(签单日期),1)=a(month(签单日期),1)+1,a(month(签单日期),2)=a(month(签单日期),2)+金额,skip,enddo,i=1,use tj1,do while i=12,if a(i,1)0,appe blank,repl 月份 with i,数量 with a(i,1),金额 with a(i,2),endif,i=i+1,enddo,list,sort on 金额 to tj2,use tj2,list,现有数据库,学生成绩,.dbf,有如下结构:lz21,学号(c,8),姓名(c,8),大学英语(n,4),语文(n,4),数学(n,4)。编程序统计出每10分间隔的三门功课的人数,并以下列形式显示:,分数段 大学英语人数 语文人数 数学人数,09 * * *,1019 * * *,2029 * * *,.,90100 * * *(vf11),use 学生成绩,dime s(10,3),s=0,do while .not.eof(),s(int(大学英语/10)+1,1)= s(int(大学英语/10)+1,1)+1,s(int(语文/10)+1,2)= s(int(语文/10)+1,2)+1,s(int(数学/10)+1,3)= s(int(数学/10)+1,3)+1,skip,enddo,clear,?分数段 英语人数 语文人数 数学人数,i=1,do while i=10,?str(i-1)*10,2)+-+str(i*10-1,3),j=1,do while jN & 意味着每个数都除不尽,SUM=SUM+I,ENDIF,ENDFOR,? 100200之间的所有素数之和为: ,SUM,CANCEL,例6.29 求出100999之间的所有水仙花数。,* PROG29.PRG,FOR I=1 TO 9,FOR J=0 TO 9,FOR K=0 TO 9,S=100*I+10*J+K,IF I3+J3+K3=S,?S,ENDIF,NEXT,NEXT,NEXT,CANCEL,结果有四个数,分别为153,370,371和407。,例6.30 求Fibonacci数列(1,1,2,3,5,8,13)的第8,15,19项的值。lz22,分析:Fibonacci数列的特点是第一项是1,第二项是1,从第三项开始,每一项等于前两项之和。利用数组是解决这类问题的最佳方法。我们将数列中的前若干项依次装入数组元素中,需要输出哪一项就输出哪个数组元素。,* PROG30.PRG,DIMENSION F(19),F(1)=1,F(2)=1,FOR I=3 TO 19,F(I)=F(I-2)+F(I-1),ENDFOR,?F(8),F(15),F(19),CANCEL,例6.31 产生10个120之间的随机整数,并将它们按升序排序后输出。,DIMENSION A(10),RAND(-1) & 将系统时间作为首个随机函数的籽值,FOR I=1 TO 10,A(I)=INT(RAND()*20)+1 & 产生120之间的随机数,?STR(A(I),5),ENDFOR,? & 以上语句的功能是建立数组,FOR I=1 TO 9 & 气泡法排序,FOR J=I+1 TO 10,IF A(I)A(J) & 按升序排序,若改为A(I)A(J),按降序排列,T=A(I) & 交换数组元素的值,A(I)=A(J),A(J)=T,ENDIF,ENDFOR,ENDFOR & 以上语句的功能是处理数组(元素),一、子程序的概念,在Visual FoxPro 中,子程序是被其他程序调用的程序文件。主程序能调用子程序,但子程序不能调用主程序。子程序也可以调用其他子程序,构成子程序的嵌套调用。在程序设计中,有些功能或计算需要在不同场合重复进行多次,这时往往将该功能或计算编写成一个独立的子程序,需要时调用它,程序既简洁又节省存储空间。事实上,不但重复执行的程序段可以作为子程序独立出去,即使只执行一次的程序段也可以编成子程序。每个子程序完成一种功能或计算,主程序的任务就是输入数据、调用子程序和输出结果这三项。,二、子程序的建立,子程序的建立和主程序一样,也是modify command 扩展名为prg.但在子程序中应有一条返回语句.Return (to master),子程序和主程序可以分别放在两个文件内;也可以放在一个文件内,此时,在子程序的开头要有Procedure,6.12 子程序,三、子程序调用语句,调用语句格式:DO WITH ,说明:WITH 是可选项,用于主程序与子程序之间的参数传递。实参表中的各项可以是常量,变量或一般表达式,互相用逗号分开。,四、子程序返回语句,返回语句格式:RETURN TO MASTER,说明:执行子程序时,遇到RETURN 命令,就返回到上一级子程序或主程序中的子程序调用命令的下一条语句继续执行。遇到RETURN MASTER命令,就径直返回主程序。通常子程序的最后一条语句是RETURN。如果缺省RETURN,程序执行到最后,自动执行RETURN语句功能,返回主调程序。,下图6-37是子程序嵌套调用时的程序执行过程示意图。,DO SUB1,CANCEL,DO SUB2,DO SUB3,RETURN,RETURN,RETURN TO MASTER,Sub1.prg,Sub2.prg,sub3,Main.prg,例6.32 求3!+5!+8!,* lz26.PRG(P、N必须在主程序中定义,STORE 0 TO SUM,P,N=3,DO JC & 调用子程序JC.PRG,SUM=SUM+P & Sum的值是3!,N=5,DO JC & 再次调用子程序JC.PRG,SUM=SUM+P,N=8,DO JC & 第三次调用子程序JC.PRG,SUM=SUM+P,? 3!+5!+8!= ,SUM,CANCEL,Procedure jc,P=1,FOR I=1 TO N,P=P*I,ENDFOR,RETURN,JC.PRG(子程序),P=1,FOR I=1 TO N,P=P*I,ENDFOR,RETURN,注:主程序负责三次调用子程序以及计算总和,子程序负责计算N!。主程序每次调用子程序时都给定N的值,子程序对给定的N值求N!,结果存入变量S。主程序执行时,遇到DO JC语句,程序转入子程序。执行子程序语句时,遇到RETURN语句,程序又返回到主程序DO JC的下一条语句继续执行。,例:main.prg,wait “下面调用子程序”,do sub1,“00000”,wait “又返回到主程序”,retu,sub1.prg,?1111111,do sub2,?1111111,Retu,sub2.prg,?2222222,retu,注意:sub11 sub2必须是单独的文件。,例:main.prg,wait “下面调用子程序”,do sub1,wait “又返回到主程序”,retu,procedure sub1,?1111111,do sub2,?1111111,Retu,Procedure sub2,?2222222,retu,注意:主程序和子程序可以放在一个文件内。,若把sub2.prg中的retu 改成retu to master,结果是什么?,五、子程序的参数传递,格式一:do with ,,格式二: (,),子程序中格式:,parameters , (,),注意:parameters 必须是被调用程序的,第一条语句,而且参数的个数和数据类型必须和被调用语句的参数相一致。,调用语句中参数可以是常量、已赋值的变量、或表达式。,在调用时参数传递关系如下:,(1)按值传递方式:实参的值只能传递给形参变量,而形参变量的值不会传递给实参变量,当形参变量的值改变时,不会影响实参变量的值,实参和形参占用不同的内存空间。,过程名 (,) 括号不能省,过程名 (,),parameters (,),(2)引用传递方式:传递实参变量的内存地址,实参变量和形参变量实际上为同一个内存单元,尽管变量名可以不同, 如果形参变量的值改变,那么实参变量的值也会跟着改变。引用传递属于双向传递。,do 过程名 with ,过程名 (,),parameters (,),(1)如果某个实参变量用一对圆括号括起来,不管采用哪种调用格式,这个实参变量总是按值传递.,(2)实参是表达式或者常量时是按值传递。,(3)在两种调用格式 下,对应的实参变量和形参变量的名字可以相同,也可以不相同.,例:set talk off(vf12),a=10,b=15,do swap with a,b,?”主程序:“,a,b,swap.prg,parameters x,y,?子程序 ,x,y,t=x,x=y,y=t,retu,clear,a=10,b=20,Swap1(a,b),? A1=,a,B1=,b,a=10,b=20,do Swap1 with a,b,? A1=,a,B1=,b,return,proc Swap1(x,y),t=x,x=y,y=t,retu,例:编程求1!+2!+N!,*jch.prg,para s,t,s=1,i=1,do while i=t,s=s*I,i=i+1,enddo,return,*vf13.prg,set talk off,input “n=“ to n,w=0,p=0,j=1,do while j=n,do jch with p,j,w=w+p,j=j+1,enddo,?”w=” ,w,STORE 100 TO X,Y lz27,PP(X,Y),?按值传递方式:,x,y,do pp with (x),(y),?按值传递方式:,x,y,do pp with x+5,y+5,?按值传递方式:,x,y,do pp with x ,y,?引用传递方式:,x,y,do pp with x,(y),?两种传递方式:,x,y,proc pp(x,y),x=x+100,y=y+50,?计算结果:,x,y,endproc,proc pp(x,y),x=x+100,y=y+50,?计算结果:,x,y,endproc,内存变量在程序中起作用的范围称为内存变量的作用域。根据作用域的不同,内存变量分为三类:局部变量、私有变量和全局变量。,(1)局部变量(本地变量),格式:LOCAL ,功能:将中的变量定义为局部变量,其作用域仅在本模块中,不能在上层或下层模块中使用。在物理上,本地变量一经定义,就临时分配了存储单元;一旦离开了本模块,局部变量所占的存储单元被释放,局部变量变成无定义,从而不能再被引用。,说明:, LOCAL命令与LOCATE命令前四个字符相同,因此不可以缩写为LOCA, LOCAL命令可以定义局部内存变量和局部数组,且它们的初值皆为.F.,例如:LOCAL A,B,C(4) & 不必再用DIMENSION语句定义C数组,?A,B,C(2),结果为 .F. .F. .F.,3内存变量的作用域,(2)私有变量,格式:PRIVATE ,功能:将中的变量定义为私有变量,其作用域在本模块及下属模块中。,说明:, PRIVATE命令可以定义私有内存变量和私有数组,且它们的初值皆为.F., 系统默认,凡在程序中没作任何说明的变量均为私有变量。它在本程序及其被调子程序中有效。, 一般情况下,私有变量不必用PRIVATE命令作显式说明。当被调子程序与主调程序中有同名变量时,可在被调子程序中对该变量作显式说明,使主调程序中的同名变量在被调子程序中暂时无效。返回主调程序后,主调程序中的同名变量原来的值仍然保留,且变量有效,而被调子程序中的变量变成无效,所占存储单元也被释放。另外,在多人开发程序时为防止主程序与各子程序之间因变量同名而互相影响,可在各自开发的子程序中定义私有变量,以屏蔽主调程序中的同名变量。,(3)全局变量(公共变量),格式:PUBLIC ,功能:将中的变量定义为全局变量,其作用域涵盖所有程序,说明:, PUBLIC命令可以定义全局内存变量和全局数组,且初值皆为.F., 在命令窗口中建立的变量和数组均为全局变量和全局数组,但这些全局变量和全局数组不能在程序中引用。, 用PUBLIC定义的全局变量和数组在整个程序运行过程中始终有效,始终占有存储单元。即使程序运行结束,系统也不会自动释放全局变量。删除全局变量只能用RELEASE 或CLEAR ALL等命令。, 若同一模块中有同名的各种变量,则优先次序为:,本地变量 私有变量 全局变量,求n到m的和,clearlz29,Input “m=” to m,Input “n=“ to n,Do sum1,?”M+N的值为:”,s,Procedure sum1,S=0,For i=n to m,s=s+I,Endfor,?”中间结果:”,s,Return,S是在子程序中开辟的变量,有效范围仅在子程序,返回到主程序时,已经从内存中消失。,()同名变量被隐藏,某级程序中使用的 局部变量,有可能和上级程序中的局部变量同名,为了避免混淆,可在子程序中用private 命令定义本级程序专用的局部变量。用private命令定义的变量,能把上级同名的变量暂时隐藏起来,彼此互不影响,子程序运行结束后,在本级程序建立的同名变量即被清除,而被隐藏的上级程序中的同名变量即被恢复出来,而且保留原值不变。,命令格式:private ,例:set talk off,a=1,b=2,do sub,?”主程序:”,a,b,retu,proc sub,private b,a=100,b=200,?”子程序:”,a,b,retu,set talk off,public aa,aa=10.2,bb=23,do fx25 with bb,?aa,bb,retu,fx25.prg,para cc,private aa,aa=20.3,cc=aa*2,Retu,set talk off,public a1,b1,store 1 to a1,b1,c1=10,do s1 with a1+b1,c1,a1,?a1,b1,c1,retu,proc s1,para x1,x2,x3,x2=x1+x3,c1=x2+x3,b1=b1+1,private b1,b1=c1*x2,return,1内部过程,定义格式:,PROCEDURE ,PARAMETERS |LPARAMETER ,RETURN ,ENDPROC,调用语句格式:,DO WITH ,说明:,(1)内部过程是作为程序中的一个独立单位出现的。它可以完成某种操作或某种运算,通常安排在本程序的后面,供本程序调用。,(2)若定义中有PARAMETERS |LPARAMETER ,称为有参过程,否则称为无参过程。有参过程的PARAMETER命令必须是第一条可执行命令,其形参(也叫虚参)最多27个。为了使过程的功能更强大,适应性更广,过程中应多使用形参。,6.3.2 过程,(3)用PARAMETERS 声明的形参变量被视为私有变量;用LPARAMETERS 声明的形参变量被视为局部变量。,(4)实参表中的各项可以是常量,变量或一般表达式,互相用逗号分开。形参表中只能是内存变量,称为形参变量。,(5)RETURN语句表示控制返回到调用语句的下一条继续执行。后跟表达式,同时返回表达式的值;不跟表达式,则返回逻辑值.T.。若缺省RETURN,则在过程结束处自动执行一条隐含的RETURN语句。,(6)PROCEDURE为过程起始语句,ENDPROC为过程结束语句。若省略ENDPROC,过程结束于下一条PROCEDURE语句或程序文件尾。,(7)有关参数传递,调用过程时,靠虚实结合进行参数传递。每个实参的值按次序一一传送给虚参变量。虚实结合是按次序而不是按名称逐一结合的。通常实参个数与虚参个数相等,形参个数多于实参个数,多余的形参取初值.F.。,虚实结合时,如果实参为常量或表达式,按值单向传送;如果实参为变量,按地址传递。,若用内存变量作实参但又不要值的回传,则可将实参变量放在一对圆括号内,使之成为表达式。,例6.34 在程序中多次调用内部过程LINE, 画一条由30个“-”组成的直线。,USE XSDA,DO LINE,FOR I=1 TO 3,DISP FIEL 学号,姓名,性别,住校否 OFF,DO LINE,SKIP,ENDFOR,USE,CANCEL,PROCEDURE LINE,FOR J=1 TO 30 & 不能使用I作为循环变量,? -,ENDFOR,RETURN,ENDPROC,例6.35 为使上述过程LINE的功能更强,适应性更广,可以增加两个虚参。,FOR I=1 TO 3,WAIT 输入一个字符: TO C,INPUT 输入字符的个数 TO N,DO LINE WITH C,N,ENDFOR,CANCEL,PROCEDURE LINE,PARAMETERS CH,M,FOR J=1 TO M,? CH,ENDFOR,?,RETURN,ENDPROC,例6.36 利用内部过程计算多边形的面积。,S=0 & 实参S必须有确定的值,AREA=0,DO TRIANGLE WITH 6.1,6.2,8.6,S,AREA=AREA+S,DO TRIANGLE WITH 8.6,7.8,2.4,S,AREA=AREA+S,DO TRIANGLE WITH 7.8,4,4.5,S,AREA=AREA+S,?多边形的面积为,STR(AREA,6,2),CANCEL,PROC TRIANGLE & 完成已知三边求面积的计算功能,PARA X,Y,Z,S & 利用形参变量S回传三角形面积,L=(X+Y+Z)/2,S=SQRT(L*(L-X)*(L-Y)*(L-Z),RETURN,ENDPROC,多边形面积,A,B,C,D,6.1,6.2,8.6,2.4,4.5,4.0,E,2外部过程,内部过程只能被本程序中的调用语句调用。外部过程是将一个过程写成一个程序文件,任何程序都可以通过调用语句对它进行调用,通用性强。,外部过程的过程名实际上就是被调用的文件主名。程序文件中的第一条语句是PROCEDURE ,这里的必须与文件主名相同,也不能省略,否则出错。PROCEDURE 这条语句可以省略,于是形式上就与前面说的子程序吻合了。,如果内部过程的过程名与外部过程的文件主名相同,调用时系统执行的是内部过程。,3过程文件,外部过程的通用性是强了,但当一个大型应用程序要调用多个外部过程时,要进行多次读盘操作,速度受影响,效率降低。另外,系统允许同时打开的文件数是有限制的。过程文件可以很好地解决这个问题。,过程文件中包含多个过程,其建立方法与一般程序文件的建立方法相同,扩展名也是.PRG。过程文件不能运行,只能打开。一旦打开,其中的所有过程均成为内部过程,供程序调用。,命令格式:,SET PROCEDURE TO ,, ADDITIVE,功能
展开阅读全文