关于单片机延时子程序流程图的问题

关于单片机延时子程序流程图的问题,第1张

延时程序在单片机编程中使用非常广泛,但一些读者在学习中不知道延时程序怎么编程,不知道机器

周期指令周期的区别,不知道延时程序指令的用法, ,本文就此问题从延时程序的基本概念、机器周期和指

令周期的区别和联系、相关指令的用法等用图解法的形式详尽的回答读者

我们知道程序设计是单片机开发最重要的工作,而程序在执行过程中常常需要完成延时的功能。例如

在交通灯的控制程序中,需要控制红灯亮的时间持续30秒,就可以通过延时程序来完成。延时程序是如何

实现的呢?下面让我们先来了解一些相关的概念。

一、机器周期和指令周期

1.机器周期是指单片机完成一个基本 *** 作所花费的时间,一般使用微秒来计量单片机的运行速度,

51 单片机的一个机器周期包括12 个时钟振荡周期,也就是说如果51 单片机采用12MHz 晶振,那么执行

一个机器周期就只需要1μs;如果采用的是6MHz 的晶振,那么执行一个机器周期就需要2 μs。

2 .指令周期是指单片机执行一条指令所需要的时间,一般利用单片机的机器周期来计量指令周期。

在51 单片机里有单周期指令(执行这条指令只需一个机器周期),双周期指令(执行这条指令只需要两个

机器周期),四周期指令(执行这条指令需要四个机器周期)。除了乘、除两条指令是四周期指令,其余均

为单周期或双周期指令。也就是说,如果51 单片机采用的是12MHz 晶振,那么它执行一条指令一般只需

1~2 微秒的时间;如果采用的是6MH 晶振,执行一条指令一般就需2~4 微秒的时间。

现在的单片机有很多种型号,但在每个型号的单片机器件手册中都会详细说明执行各种指令所需的机

器周期,了解以上概念后,那么可以依据单片机器件手册中的指令执行周期和单片机所用晶振频率来完成

需要精确延时时间的延时程序。

二、延时指令

在单片机编程里面并没有真正的延时指令,从上面的概念中我们知道单片机每执行一条指令都需要一

定的时间,所以要达到延时的效果,只须让单片机不断地执行没有具体实际意义的指令,从而达到了延时

的效果。

1.数据传送指令 MOV

数据传送指令功能是将数据从一个地方复制、拷贝到另一个地方。

如:MOV R7,#80H   ;将数据80H 送到寄存器R7,这时寄存器R7 里面存放着80H,就单这条

指令而言并没有任何实际意义,而执行该指令则需要一个机器周期。

2.空 *** 作指令 NOP

空 *** 作指令功能只是让单片机执行没有意义的 *** 作,消耗一个机器周期。

3.循环转移指令 DJNZ

循环转移指令功能是将第一个数进行减1 并判断是否为0,不为0 则转移到指定地点;为0 则往下执行。

如:DJNZ R7,KK ;将寄存器R7 的内容减1 并判断寄存器R7 里的内容减完1 后是否为0,如果

不为0 则转移到地址标号为KK 的地方;如果为0 则执行下一条指令。这条指令需要2 个机器周期。

利用以上三条指令的组合就可以比较精确地编写出所需要的延时程序。

三、1 秒延时子程序、流程图及时间计算 (以单片机晶振为12MHz 为例,1 个机器周期需要1μs)

了解了以上的内容,现在让我们来看看

程序总共所需时间:1+10+2560+330240+660480+5120+20+2=998433 μs≈1S

在这里运行这段程序共需998433 μs,还差1567μs 才达到1S 的,所以想要达到完美的1S 延时,需

要在返回指令RET 前再添加一些指令让它把1567μs 的延时完成。有兴趣的读者可以自己试着添加完成。

最后补充一点,编写程序时一般将延时程序编写成独立的子程序,而所谓子程序也就是一个实现某个功能

的小模块。这样在主程序中就可以方便地反复调用编写好的延时子程序。

小提示:循环转移指令(DJNZ )除了可以给定地址标号让其跳转外,还可以将地址标号改成$,这样

程序就跳回本指令执行。例如:

DJNZ R7,$ ;R7 内容减1 不为0,则再次执行本指令;为0 则往下执行,当R7 的值改为10

时,则执行完该条程序所需的时间为2*10=20 μs。

51单片机汇编延时程序算法详解

将以12MHZ晶振为例,详细讲解MCS-51单片机中汇编程序延时的精确算法。

指令周期、机器周期与时钟周期

指令周期:CPU执行一条指令所需要的时间称为指令周期,它是以机器周期为单位的,指令不同,所需的机器周期也不同。

时钟周期:也称为振荡周期,一个时钟周期 =晶振的倒数。

MCS-51单片机的一个机器周期=6个状态周期=12个时钟周期。

MCS-51单片机的指令有单字节、双字节和三字节的,它们的指令周期不尽相同,一个单周期指令包含一个机器周期,即12个时钟周期,所以一条单周期指令被执行所占时间为12*(1/12000000)=1μs。

程序分析

例1 50ms 延时子程序:

DEL:MOV R7,#200 ①

DEL1:MOV R6,#125 ②

DEL2:DJNZ R6,DEL2 ③

DJNZ R7,DEL1 ④

RET ⑤

精确延时时间为:1+(1*200)+(2*125*200)+(2*200)+2

=(2*125+3)*200+3 ⑥

=50603μs

≈50ms

由⑥整理出公式(只限上述写法)延时时间=(2*内循环+3)*外循环+3 ⑦

详解:DEL这个子程序共有五条指令,现在分别就 每一条指令 被执行的次数和所耗时间进行分析。

第一句:MOV R7,#200 在整个子程序中只被执行一次,且为单周期指令,所以耗时1μs

第二句:MOV R6,#125 从②看到④只要R7-1不为0,就会返回到这句,共执行了R7次,共耗时200μs

第三句:DJNZ R6,DEL2 只要R6-1不为0,就反复执行此句(内循环R6次),又受外循环R7控制,所以共执行R6*R7次,因是双周期指令,所以耗时2*R6*R7μs。

例2 1秒延时子程序:

DEL:MOV R7,#10 ①

DEL1:MOV R6,#200 ②

DEL2:MOV R5,#248 ③

DJNZ R5,$ ④

DJNZ R6,DEL2 ⑤

DJNZ R7,DEL1 ⑥

RET ⑦

对每条指令进行计算得出精确延时时间为:

1+(1*10)+(1*200*10)+(2*248*200*10)+(2*200*10)+(2*10)+2

=[(2*248+3)*200+3]*10+3 ⑧

=998033μs≈1s

由⑧整理得:延时时间=[(2*第一层循环+3)*第二层循环+3]*第三层循环+3 ⑨

此式适用三层循环以内的程序,也验证了例1中式⑦(第三层循环相当于1)的成立。

注意,要实现较长时间的延时,一般采用多重循环,有时会在程式序里加入NOP指令,这时公式⑨不再适用,下面举例分析。

例3仍以1秒延时为例

DEL:MOV R7,#10 1指令周期1

DEL1:MOV R6,#0FFH 1指令周期10

DEL2:MOV R5,#80H 1指令周期255*10=2550

KONG:NOP 1指令周期128*255*10=326400

DJNZ R5,$ 2指令周期2*128*255*10=652800

DJNZ R6,DEL2 2指令周期2*255*10=5110

DJNZ R7,DEL1 2指令周期2*10=20

RET 2

延时时间=1+10+2550+326400+652800+5110+20+2 =986893μs约为1s

整理得:延时时间=[(3*第一层循环+3)*第二层循环+3]*第三层循环+3 ⑩

结论:针对初学者的困惑,对汇编程序的延时算法进行了分步讲解,并就几种不同写法分别总结出相应的计算公式,只要仔细阅读例1中的详解,并用例2、例3来加深理解,一定会掌握各种类型程序的算法并加以运用。

单片机延时子程序

1)延时为:20ms 晶振12M

1+(1+2*248+2)*4+1+1+1=20000US=20MS

用汇编..优点就是精确...

缺点就是算有点复杂.

DELAY20MS:

MOV R7,#4

D1:

MOV R6,#248

DJNZ R6,$

DJNZ R7,D1

NOP

NOP

RET

2)一些通过计算51汇编指令得出的软延时子程序

*****************************************************************

延时10uS

*****************************************************************

time10us:               mov     r5,#05h                 11us

djnz    r5,$

ret

*****************************************************************

延时50uS

*****************************************************************

time50us:               mov     r5,#19h                 51us

djnz    r5,$

ret

*****************************************************************

延时100uS

*****************************************************************

time100us:              mov     r5,#31h                 99.6us

djnz    r5,$

ret

*****************************************************************

延时200uS

*****************************************************************

time200us:              mov     r5,#64h                 201us

djnz    r5,$

ret

*****************************************************************

延时250uS

*****************************************************************

time250us:              mov     r5,#7ch                 249.6us

djnz    r5,$

ret

*****************************************************************

延时350uS

*****************************************************************

time350us:              mov     r5,#0afh                 351us

time350us_1:            djnz    r5,time350us_1

ret

*****************************************************************

延时500uS

*****************************************************************

time500us:              mov     r5,#0fah                 501us

time500us_1:            djnz    r5,time500us_1

ret

*****************************************************************

延时1mS

*****************************************************************

time1ms:                mov     r5,#0fah                1001us

time1ms_1:              nop

nop

djnz    r5,time1ms_1

ret

*****************************************************************

延时2.5mS

*****************************************************************

time2_5ms:              mov     r5,#05h          2.496ms

time2_5ms_1:            mov     r6,#0f8h         497us

djnz    r6,$

djnz    r5,time2_5ms_1

ret

*****************************************************************

延时10mS

*****************************************************************

time10ms:               mov    r5,#14h         10.262ms

time10ms_1:             mov    r6,#0ffh        511us

djnz   r6,$

djnz   r5,time10ms_1

ret

*****************************************************************

延时50mS

*****************************************************************

time50ms:               mov    r5,#63h         49.996ms

time50ms_1:             mov    r6,#0fbh        503us

djnz   r6,$

djnz   r5,time50ms_1

ret

*****************************************************************

延时100mS

*****************************************************************

time100ms:              mov     r5,#0c3h        100.036ms

time100ms_1:            mov     r6,#0ffh        511us

djnz    r6,$

djnz    r5,time100ms_1

ret

*****************************************************************

延时200mS

*****************************************************************

time200ms:              mov     r5,#02h         250.351ms

time200ms_1:            mov     r6,#0f4h        125.173ms

time200ms_2:            mov     r7,#0ffh        511us

djnz    r7,$

djnz    r6,time200ms_2

djnz    r5,time200ms_1

ret

*****************************************************************

延时500mS

*****************************************************************

time500ms:              mov    r5,#04h         500.701ms

time500ms_1:            mov    r6,#0f4h        125.173ms

time500ms_2:            mov    r7,#0ffh        511us

djnz   r7,$

djnz   r6,time500ms_2

djnz   r5,time500ms_1

ret

*****************************************************************

延时1S

*****************************************************************

time1s:                 mov    r5,#08h         1001.401ms

time1s_1:               mov    r6,#0f4h        125.173ms

time1s_2:               mov    r7,#0ffh        511us

djnz   r7,$

djnz   r6,time1s_2

djnz   r5,time1s_1

ret

12M晶振 机器周期为1US  NOP为单周期指令 DJNZ为双周期指令.

3)

晶振12MHZ,延时1秒

DELAY:MOV   72H,#100

LOOP3:MOV   71H,#100

LOOP1:MOV   70H,#47

LOOP0:DJNZ   70H,LOOP0

NOP

DJNZ   71H,LOOP1

MOV   70H,#46

LOOP2:DJNZ   70H,LOOP2

NOP

DJNZ   72H,LOOP3

MOV   70H,#48

LOOP4:DJNZ   70H,LOOP4

4)延时1分钟子程序,F=6MHz

程序已测过,延时时间60,000,000.0uS

delay60s:mov r3,#228

mov r2,#253

mov r1,#219

loop1:   djnz r1,$

djnz r2,loop1

djnz r3,loop1

nop

ret

5)计算机反复执行一段程序以达到延时的目的称为软件延时,单片机程序中经常需要短时间的延时,但是相当一部分人对延时程序很模糊,对延时程序的算法不够了解,在这里我以12MHz晶振和两个经典延时子程序为例,详细分析单片机汇编延时程序。

何为时钟周期、机器周期、和指令周期?

时钟周期:也就是振荡周期,以12MHz的时钟脉冲为例,那时钟周期就为(1/12000000)s=(1/12)us;

机器周期:1个机器周期=6个状态周期=12个时钟周期=1us;

指令周期:CPU执行一条指令所需要的时间称为指令周期,指令周期是以机器周期为单位的,不同的指令所需的机器周期不一定相同,可参考51单片机指令速查表。

由上可得:CPU执行一条单周期指令,需要1us;执行一条双周期指令需要2us。

下面是具体的延时子程序分析:

0.1s延时子程序(12MHz晶振):

MOV R7,#200   单周期指令(1us)

D1:     MOV R6,#250   单周期指令(1us)

DJNZ R6,$      双周期指令(2us)//该指令自身执行R6次

DJNZ R7,D1     双周期指令(2us)//D1执行R7次

RET            双周期指令(2us)

T=1+(1+2*R6+2)*R7+2

=100603us

≈0.1s

0.5s延时子程序(12MHz晶振):

MOV R7,#5     单周期指令(1us)

D1:     MOV R6,#200   单周期指令(1us)

D2:     MOV R5,#250   单周期指令(1us

DJNZ R5,$      双周期指令(2us)//该指令自身执行R5次

DJNZ R6,D2     双周期指令(2us)//D2执行R6次

DJNZ R7,D1     双周期指令(2us)//D1执行R7次

RET            双周期指令(2us)

T=1+[1+(1+2*R5+2)*R6+2]*R7+2

=503018us

≈0.5s

6) 51单片机经典流水灯程序,在51单片机的P2口接上8个发光二极管,产生流水灯的移动效果。

ORG        0                   程序从0地址开始

START:      MOV      A,#0FEH     让ACC的内容为11111110

LOOP:         MOV      P2,A            让P2口输出ACC的内容

RR          A                  让ACC的内容左移

CALL     DELAY       调用延时子程序

LJMP     LOOP          跳到LOOP处执行

0.1秒延时子程序(12MHz晶振)===================

DELAY:      MOV      R7,#200      R7寄存器加载200次数

D1:               MOV      R6,#250      R6寄存器加载250次数

DJNZ     R6,$             本行执行R6次

DJNZ     R7,D1          D1循环执行R7次

RET                            返回主程序

END                           结束程序

我先给你一些VF的例题看看吧!

Vfp--程序设计典型例题

Vfp题库:程序设计基础 典型例题

[例1] 在( )窗口中可以控制列表框内显示的变量种类。

A.跟踪窗口 B.监视窗口

C.局部窗口 D.调动堆栈窗口

分析:局部窗口用于显示模板程序中的内存变量,并显示它们的名称.当前取值的类型。它可以控制在列表内显示的变量类型。

答案c

例2下面选项中关于ACCEPT命令说法错误的是()

A.ACCEPT命令格式是:ACCEPT[<字符表达式>] TO<内存变量>

B.该命令只接收字符串,但是用户在输入字符串时,必须要加上定界符

C如果不输入任何内容直接按回车键,系统就会把空串赋给指定的内存变量

D如果选用<字符表达式>,那么系统就会首先显该表达式的值,作为提示信息

分析:该命令只接收字符串,但用户在输入时不需要加定界符否则,系统会把定界符当作字符串的一部分输出.

答案:B

例3下列关于过程的说法中不正确的是

A.过程文件可以放在任何程序文件代码的后面,也可以保存在称为过程文件的单独文件里

B.过程文件只包含过程,这些过程只能被过程文件调用

C.如果需要打开多个过程文件,可以在调用过程语句中加ADDITVE,那么在打开过程文件时,

并不关闭原先已打开的过程文件

D.关闭个别过程文件的命令格式是:RELESE PROCEDURE<过程文件>

分析:过程文件只包含过程,这些过程可以被任何其它程序调用.命令格式SETPOCEDURE TO[<过程文件>][ADDITIVE]就可以打开多个过程文件.当使用不带任何文件名的SET PROCEDURE TO命令时,将会关闭所有的过程文件,使用命令RELEASE PROCEDURE<过程文件>时,将关闭指定的过程文件.

答案:B

例4 在一个程序定义了的一些变量,选出局部变量 ( )

1.PRG

PUBLIC aI

LOCAL a2,a3

SCORE'B'TO a4

LOCATE a5

A.a1 B.a2,a3

C.a4 D.a5

分析:A是公共变量,C是私有变量,D的命令和LOCATE相似,但不存在这样定义变量的命令.只有B才是定义了两个局部变量.

答案:B

例5 不需要先建立就可以使用的变量是 ( )

A.局部变量 B.公共变量

C.私有变量 D.数组

分析:私有变量是指在程序中直接使用,由系统自动隐含建立的变量.即没有通过PUBLIC 或LOCAL定义的变量.它的作用域是建立它的模块及其下属的各层模块.私有变量随着建立它的模块运行结束自动清除,不需要先建立就可以使用.

答案:C

「例6」可以设置表达式类型的断点窗口是 ( )

A.跟踪窗口 B.监视窗口 C.局部窗口 D.调用堆栈窗口

分析:监视窗口主要就是用来指定表达式在程序调试执行过程中的变化。要设置一个监视表达式,只需单击窗口中的“监视”文本框,然后输入表达式的内容,按回车键后表达式便添入文本框下方的列表框中。

答案:B

「例7」下列命令语句正确的是 ( )

A.INPUT〃请输入账号〃TO zh B.INPUT〔2001-03-01〕TO rq

C.INPUT〃T〃TO sa D.INPUT〃∧2001-03-01〃TO zh

分析:B的正确写法是:INPUT〔∧2001-03-01〕TO rq;C的正确写法是:INPUT.T.TO sa。

答案:A

「例8」阅读下列程序,该程序的运行结果是 ( )

SET TALK OFF

INPUT〃请输入A,B:〃TO A,B

IF A〈 B

T = A

A = B

B = T

ENDIF

DO WHILE B〈 〉0

T = MOD(A,B)

A = B

B = T

ENDDO

?A

SET TALK ON

RETURN

运行时输入:12,8

A.2 B.4 C.12 D.8

分析:本程序的功能是求两个数的最大公约数。方法是用两个数中较小的去除较大的,然后将除数作为一次除的被除数,余数作为下一次除的除数,反复进行这样的 *** 作,直到余数为零时为止。则最后一次除的除数,即为所给两个数的最大公约数。

答案:B

「例9」用于说明程序中所有内存变量都是局部变量的命令是 ( )

A.PRIVATE ALL B.PUBLIC ALL

C.ALL=PRIVATE D.STORE PRIVATE TO ALL

分析:定义局部变量的语句有PRIVATE<内存变量名表>和PRIVATE ALL(LIKE/EXCEPT<通配符>)。在使用PRIVATE ALL本程序中所有内存变量都说明为局部变量。

答案:A

(例10)在Visual FoxPro中,用于建立过程文件PROGI的命令是 ( )

A. CREATE PORGI B. MODIFY COMMAND PROGI

C. MODIFY PROGI D. EDIT PROGI

分析: 在Visual FoxPro中,建立程序的命令是MODIFY COMMAND

答案:B

例11:一个过程文件最多可以包含128个过程,其文件扩展名是 ( )

A. PRG B. FOX

C. DBT D. TXT

分析: 过程文件也是一种命令文件,扩展名为.PRG

答案:A

例12:有Visual FoxPro程序如下:

SET TALK OFF

USE CJ

M - >ZF=0

DO WHILE.NOT.EOF()

M - >ZF=M - >ZF+ZF

SKIP

ENDDO

?M - >ZF

RETURN

其中数据库文件CJ.DBF中有2条记录,内容如下:

XM ZF

1 李四 500.00

2 张三 600.00

运行该程序的结果应当是

A.1100 B.1000

C.1600 D.1200

分析:分析该程序的结果时,只要理解“M - >ZF”的含义,程序就没有社么难度了。

答案:A

例13:在命令文件中,调用另一个命令文件。应使用命令

分析:在FoxPro系统中,LOAD命令用于将一个二进制文件调人内存,CALL命令执行一个已调人内存的二进制文件。PROCEDURE仅在程序中说明过程名,每个过程以PROCEDURE<过程名>开始,用PETURN结束,不是调用程序。要在命令文件中调用另一个命令文件应该使用命令DO<命令文件名>.

答案: DO〈命令文件名〉

[例14]有下列程序:

PARAMETER A,B,C,D

D=B* B-4*A*C

DO CASE

CASE D=O

CASE D〈O

D=O

CASE D〉O

D=2

CASE D=O

D=1

ENDCASE

在主程序中执行如下命令:

STORE 2 TO A,C

DO SUB WITH A,B,C,D

?D

D的值为—————

分析:执行主程序DO SUB WITH A,B,C,D时,把实参1,2,1,2传递给形参A,B,C,D。在执行过程

SUB中语句D=B*B-4*A*C后的D值为O,然后执行DO CASE/ENDCASE语句,条件CASE D=O成立,重新赋值D=1,

最后返回主程序时,把形参A,B,C,D的值1,2,1,1传给对应实参A,B,C,D此时D的值为1。

答案: 1

[例15]有如下程序:

STORE O TO N,S

DO WHILE.T.

N=N+1

S=S+N

IF N>=1O

EXIT

ENDIF

ENDDO

?”S=“+STR(S,2)

本程序的运行结果是—————

分析:本程序是无限次循环程序,有N的值来决定何时停止循环。程序的功能是求1到1O之间的所有整数之

和。可得程序运行的结果为S=55

答案:S=55

[例16]有如下程序:

*主程序:MAIN。PRG

SET TALK OFF

CLEAR

S=0

DO SUB WITH 10,S

?S

RETU

*子程序SUB。PRG

PARAMETERS D1,D2

D1=D1+D1

D2=D1*2

RETURN

执行主程序后S的值是__________。

分析:DO...WITH语句中的实在参数除了可以是变量外,还可以是任意有数或表达式。当为常数时,

直接把值传给对应的形参;当为表达式时,先求其值后把其值传给形参。主程序中变量S的初值为0,

S调用子程序SUB,将数值10和0对应传给子程序中的参数D1和D2,执行D1=D1+D1后,D1=20,再执行D2

=D1*2,D2=40,返回到主程序时D2将值回传给S。因此,在主程序执行?S时,屏幕显示40。

答案:40

[例17]设成绩库CJK.DBF中“数学”(数值型字段)这门课程的学分为4,其学分计算的方法如下:

数学>=90,学分值为4

80<=数学<90,学分值为3

70<=数学<80,学分值为2

60<=数学<70,学分值为1

数学<60,学分值为0

计算任一学生数学这门课程的学分值的程序如下:

SET TALK OFF

USE CJK

ACCEPT "输入学号:" TO XH

XF=0

LOCATE FOR学号=XH

DO CASE

CASE______

XH=40

CASE______

XH=3

CASE__________

XF=2

CASE__________

XF=1

OTHERWISE

XF=0

ENDCASE

?"学号:",XH

?"数学的学分值:",XF

USE

RETURN

分析:本程序的考核要点是DO CASE分支语句

答案:数学>=90 数学>=80 数学>=70 数学>=60

【例18】参数的两种传递方法是_______和_______。

分析:调用程序模块时,如果实参是常量或一般形式的表达式,系统会计算出实参的值,并把它们赋值

给相应的形参变量。这种情形称为按值传递。如果实参是变量,那么传递的将不是变量的值,而是变量

的地址。这时形参和实参实际上是同一个变量,在模块程序中对形参变量值的改变,同样是对实参变量

值的改变,这种情形称为引用传递。

答案:TO VALUE(按值传递),REFERENCE(按引用传递)

【例19】填空完成下列程序,要求该程序能够三次从右向左显示变量S内容的字幕程序。

CLEAR

S=SPACE(80)+"关系数据库语言VFP计算机2级教程。关系数据库."

+SPACE(60)

N=0

______

I=1

DO WHILE I<160

@20,0SAY SUBSTR(S,I,80)

H=INKEY(0.1,"h")

I=I+2

_____

_____

ENDDO

分析:表达式(1)是给出循环的条件,表达试(3)给出循环体的递增形式。

答案:(1)DO WHILE N<3,(2)ENDDO,(3)N=N+1

【例20】用两种循环步长值来求1+2+3+...50的值,请将程序填写完整。

程序一:

S=0

FOR__(1)___

S=S+N

ENDFOR

? S

RETURN

程序二:

S=0

FOR__(2)___

S=S+N

ENDFOR

?S

RETURN

分析:这是一个计数循环的例子,由以上两种方法可以看出,初值和终值的设定是随步长值不同而变化

的,在程序一中,由于步长为1,所以省略了。缺省时,步长值默认为1。

答案:(1)N=1 TO 50,(2)N=50 TO 1 STEP -1

[例21] 求30!,请将程序填写完整。

程序:N=1

I=I*N

N=N+1

ENDDO

?I

分析:在进入循环前,必须组织好循环使累加器先赋初值勤,循环条件表达式中的控制变量也要根据

不同情况赋初值,因为循环的次数是和条件表达式中的控制变量所赋的初值密切相关的。循环体包括了

在循环体中的书写顺序也与循环的初始赋值有关。读者可以考虑一下,如果给N赋上班,那么DO WHILE

后面的条件表达式该怎么来写?

答案:N<=30

[例22] 为了解决在子程序和主程序之间可能会出现变量的重复使用命令_______,这样可以使主程序中

的变量暂时在子程序中无效,而不改变它的值。

分析;为了避免子程序和主程序之间变量带来的问题,可以使主程序中使用命令PRIVATE隐藏主程序

中可能存在的变量,使得在子程序中暂时无效。该命令的语法格式是:

PRIVATE<内存变量表>

答案:private<内存变量表》

例23 统计银行客房关系表中,银行代码为001,并且存款金额大于1500元的客房人数,请将程序填写完整。

程序:

clear

open银行客户关系表exclusive

browse all for银行代码=“001”

count all to kh

goto top

num=0

for(1)

if(2)

num=num+1

endif

skip

endfor

@2,30 say"银行代码为001,存款金额大于1500元的人数有:“num+””

endif

use

分析:在该例中,for语句使用了循环变量1控制 *** 作,道德计算出了数据表中所含记录个数num,

然后把它人微言轻循环变量的终值,使循环变量从1开始,多次加入循环变量步长,直到循环变量1大于

num时才结束循环。

答案:(1)I=1 to kh step1,(2)金额>“1500”and,银行代码=“001”

例24 下例是关于参数传递的程序,求出正确结果。

程序:

clear

store 3 to a,b

store 2 to c,d

do tub with a,b,c,d

?b

store 4 to t2,t1

store 1 to t4,t3

do tub with t1,t2,t3,t3

?t4

do tub with 6,6,3,b

?b

procedure tub

PARAMETER A,B,C,D

B=A* A-4 *C* D

DO CASE

CASE B<0

B=120

CASE B>0

B=210

CASE B=0

B=100

ENDCASE

RETURN

分析: 在程序开始对A,B赋值为3,对C,D赋值为2。然后把实参A、B、C、D传递给予程序TUB,根据表达式B=A*A-4*c*D

计算出结果为-7,所以输出结果为120,同样,以下程序执行时,根据表达式的计算结果,输出依次为1和6。

答案:结果显示在3行上,依欠为120,1,6

[例25] 根据输入的半和径值,计算圆的面积,请将程序填写完整。

程序:

CLEAR

R=0

SM=0

@12,15 SAY “输入圆半径” CET R

READ

IF R=0

EXIT

ENDIF

————

@16,16 SAY“圆的面积为:”+ ALLTRIM(STR(SM))

ENDDO

RETURN

计算圆面积的函数:

FUNCTION AREA

PARAMETERS A

S=3.1415926*A*A

RETURN

分析:该语句是实现对计算圆面积函数的调用,返回值赋给变量SM。这个程序所使用的是一个自定义函数,自定义函数和

子程序的区别就是自定义函数必须返回一个函数值,而子程序没有这个限制。自定义函数的编辑方法和子程序的编辑方法相同,只是要把子程序文件名改为自定义函数名。

需要注意的几点是:自定义函数能以独立的文件存储,也可包含在调用程序中作为它的一部分。如果[FUNCTION<函数名>]缺省,这表示该函数是一个独立的文件。另外,自定义函数不能与系统函数同名,也不能与内存变量同名。

答案:SM=AREA(R)

例26 当变量I在奇偶之间变化时,求出下面程序的输出结果。

程序:

CLEAR

I=O

DO WHILE I<10

IF INT(I/2)=I/2

?"W"

ENDIF

?"T"

I=I+1

ENDDO

分析:该程序应用的是循环和条件嵌套的结构。

答案:W,T,T连续显示5次

[例27] 填空完成下列程序,仅接受输入Y和N的程序,否则程序结束。

DO WHILE .T.

WAIT "请输入Y/N" TO AS

IF UPPER(AS)<>"Y"AND UPPER(AS) <>"N"

(1)

ELSE

(1)

ENDIF

ENDDO

分析:该例是一个条件循环,选用EXIT是强制推出循环条件,执行它能够立即跳出循环,执行ENDDO

后面的语句。选用LOOP则是一种强制缩短循环的语句,其功能是终止本次循环体语句的执行,把控制转到

循环结构的开始。

答案: (1)EXIT,(2)LOOP

[例28] 当变量X的值变化时,依次显示其结果,注意循环体内的LOOP和EXIT语句。

程序:

CLEAR

X=3

DO WHILE .T.

X=X+1

IF X=INT(X/3)*3

?x

ELSE

LOOP

ENDIF

IF X>10

EXIT

ENDIF

ENDDO

RETURN

分析:INT()是取整数函数

如果循环体内有LOOP命令,那么当晕到LOOP时,就结束循环的本次执行,不再执行其后的语句,而是转回DO WHILE

处重新判断条件。

如果循环体包括EXIT命令,那么当遇到EXIT时,就结束该循环语句的执行,转去执行ENDDO后面的语句。

通常LOOP或EXIT出现在循环体内嵌套的选择语句时,根据条件来决定是LOOP回去,还是EXIT出去。

答案:依次显示为:6,9,12

[例29] 填空完成下列程序,求数绝对值的程序。

INPTU’请输入一个数:‘TO X

?STR(X)+“它的绝对值是:’+STR(f(x))

FUNCTION F

(1)

———

IF T>=0

T=T

ELSE

T=-T

ENDIF

RETURN T

分析:FUNCTION 是一个子函数,语句PARAMETERS是定义子函数里面的变量。

[例30] 如果说用DO命令来执行查询文件、菜单文件、那么<文件名>中必须名含——————。

分析:VISUAL FOXPRO 程序文件通过编辑、连接,可以产生不同的目标代码文件,这些文件具有不同的文件名。

当用DO 命令执行程序文件时,如果没有指定扩展名,系统将按下列顺序寻找程序文件的源代码或某种目标代码文件

执行:.EXE->.APP->.FXP->.PRG但是用DO命令来执行查询文件、菜单文件时,那么<文件名>中必须包括扩展名。

答案:扩展名(.QBR或.MPR)

[例31]打开银行客户关系表,输入一个控制口令控制程序的执行,若口令为1,则把

“银行代码”为“001”的所有记录加上删除标记;若口令为2,把“银行代码”为“002”的所有记录

加上删除标记;若口令为3,把“银行代码”为“003”的所有记录加上删除标记。请将程序填写完

整。

程序:

CLEAR

USE银行客户关系表EXCLUSIVE

BROWSE LAST

WATT“请输入你的选择:(1-3)”TO yhdm

DO CASE

CASE (1)

DELETE ALL FOR 银行代码=“001”

BROWSE ALL FOR银行代码=“001”

RECALL

CASE (2)

DELETE ALL FOR 银行代码=“002”

BROWSE ALL FOR 银行代码=“002”

RECALL

CASE (3)

DELETE ALL FOR 银行代码=“003”

BROWSE ALL FOR 银行代码=“003”

RECALL

ENDCASE

BROWSE

USE

分析:该程序执行时,依次判断语句中列出的条件,当碰到取值为真时就执行该条件下的语句序列。

答案:(1)yhdm=“1”,(2)yhdm=“2”,(3)yhdm=“3”

例32 按银行帐号显示存款记录,如果该帐号不存在,则会显示空记录,请将该程序

填写完整。

程序:

CLEAR

USE KH

帐号=SPASE(5)

@10.4 SAY "请出入要查循学生的学号:” CET帐号

READ

----------------

USE

分析:该程序可以实现查询功能,但是它显示不出客户信息的异常情况,也不能向用户显示错误提示信息,而且每调用一次程序只能查询一个客户的情况。

答案:disp for 帐号=ALLTRIM(KH)

例 34 查询客户情况,如果查到了就显示客户的存款信息,查不到就什么都不显示,请将程序填写完整。

程序:

CLEAR

USE KH

帐号=SPACE(15)

@ 10,4 SAY"请输入要查询的客户信息:" GET帐号

READ

LOCATE FOR 帐号=ALLTRIM(帐号)

IF (1)

@ 6,10 SAY"帐号是"+帐号+"的客户存款情况为:"

?金额,存款类型

ENDIF

USE

分析: 这是一个单边选择的程序,如果不满足条件,就自动执行下一条语句。

答案: NOT EOF()


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/yw/7697055.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-04-08
下一篇 2023-04-08

发表评论

登录后才能评论

评论列表(0条)

保存