本章要点:
顺序控制结构的程序设计
选择控制结构的程序设计
循环控制结构的程序设计第 3章 三种结构的程序设计
3.1 顺序控制结构顺序控制结构是程序设计中最简单、最常用的基本结构。在顺序控制结构中,各程序段按照出现的先后顺序依次执行。它是任何程序的基本结构。
程序流程控制语句是用来控制程序中各语句执行顺序的语句,是程序中非常关键和基本的部分。程序流程控制语句可以把单个的语句组合成有意义的、能完成一定功能的小逻辑模块。 1966年 Bohm和 Jacopini
证明了任何复杂的算法都可以用顺序、选择、循环三种结构组合而成,
所以这三种结构称为程序的三种基本控制结构。合理地使用流程控制语句在很大程度上影响了编写程序的质量。在一段程序中,计算机按照语句顺序执行,当遇到选择结构、循环结构时,就有可能改变执行顺序。
3.1.1 程序流程控制语句
3.1.2 顺序控制结构 (1)
顺序控制结构是计算机按照语句的前后顺序依次执行的程序结构。在顺序控制结构中,程序依次地经过输入、处理到最后的输出。 Delphi 7.0提供了基本的输入 /输出控件(在第 7章中将给予介绍)。对于顺序控制结构来说,
组成程序体主要语句就是赋值语句。接下来通过一个实例来说明顺序控制结构的程序设计方法。
1,主要步骤
进入 Delphi 7.0后在 standard标签页中找到相关组件,设计如图 3-1窗体及有关对象。
分别在窗体的建立、小写按钮单击和大写按钮单击事件中输入如下代码。
图 3-1 大小写转换程序
procedure TForm1.FormCreate(Sender,TObject);
begin
edit1.Text:=''; //初始化文本框,使其为空
end;
procedure TForm1.Button1Click(Sender,TObject);
var s:string;
begin
s:=edit1.Text;
edit1.Text:=lowercase(s); // 转换成小写
end;
【 例 3-1】 大小写转换程序。
3.1.2 顺序控制结构 (2)
procedure TForm1.Button2Click(Sender,TObject);
var s:string;
begin
s:=edit1.Text;
edit1.Text:=uppercase(s); //转换成大写
end;
2,分析在窗体的建立事件中,首先将文本框的内容进行清空(以便输入)。在
button1按钮事件中有两个语句,先将文本框的内容赋给一个字符串变量 s,
然后通过一个 lowercase函数将其转换成小写后再在文本框中显示。而
button2按钮事件和 button1基本类似,惟一不同的是将其转换成大写而已。可以看到,在每一个事件代码中,其语句都是顺序执行的。这就是这种结构的特点。
3,运行结果程序运行结果如图 3-2所示。
(图 3-2 大小写转换程序运行结果 )
3.2 选择控制结构标识符 是 Object Pascal语言中用来表示应用程序量的名称。包括:
变量 (Var)、常量 (Const)、类型 (Type)、过程 (Procedure)、方法 (Method)
等。
在日常生活和工作中,经常需要根据给定的条件进行分析、比较和判断,以采取相应的操作。例如,有如下分段函数:
在计算函数值时,首先应根据 x的值进行判断,当 x≥0时,y的值是 x的平方;
否则 y的值是 x的三次方。
选择控制结构是计算机用来描述自然界和社会生活中分支现象的重要手段。其特点是:根据所给定的条件为真与否,决定从各实际可能的不同分支中执行某一个分支的相应操作,并且任何情况下总有一种分支相对应。
Object Pascal中的分支语句有 If语句和 Case 语句。
)0(
)0(
3
2
xx
xx
y


3.2.1 If语句 (1)
If语句又称为条件语句,是最常用的单条件选择结构。 If语句的语法格式为:
if <条件> then 条件语句 1语句 2假真
[<语句 1> ]
[else
<语句 2>=;
条件语句一 语句二真 假其中<条件>可以是关系表示式或布尔表达式,它的值是真( True)或假
( False)。如果<条件>的值为真则执行
<语句 1>,否则执行<语句 2>,If语句所对应的流程图如图 3-3所示。
图 3-3 if语句因为 if…then…else 语句是一个完整的语句,因此在 else之前没有分号,如果加入分号将产生编译错误。<语句>可以是简单语句也可以是复合语句还可以为空语句。当然,<语句 1>、<语句 2>同时为空语句时 If语句就失去了意义。
3.2.1 If语句 (2)
If语句分为简单条件语句和复合条件语句两种 。
1,简单条件语句简单条件语句的<语句>中不包含其他的条件语句。
【 例 3-2】 输入 x计算 y的值,其中:
分析:这是一个分支函数,对应 x的值不同,计算时使用的表达式不同,因此可以用条件语句实现对表达式的选择。
var x,y:double;
begin
if x>=1 then
y:=x*x+2*x
else
y:=2*x+1;
end;
注意,if…then…else 语句是一个完整的语句,因此在 else之前没有分号,如果加入分号则产生错误。


)1(2
)1(12
2 xxx
xx
y


3.2.1 If语句 (2)
2,复合条件语句如在 If语句格式中的<语句 1>或<语句 2>本身又是一个 If语句,则称为 If
语句的嵌套。嵌套的 If语句又被称为复合条件语句。来看本教程 P40页的例子。
由于 If语句有两种,一种是有 else语句,一种无 else语句。对复合条件语句有可能有二义性,即可能有两种不同的理解,如下所示:
if <条件 1> then
if <条件 2> then
<语句 1>
else <语句 2>
一种理解是 else 语句是与后一个 then 语句配对,另一种理解是 else 语句是与前一个 then 语句配对,两种理解的效果是不一样的。 Object Pascal规定:
else总是与同一层的前面最靠近它的、还没有 else语句与之配对的 then配对。
因此第一种理解是正确的,else语句是与后一个 Then 语句配对。
3.2.2 case语句对于多分支选择的情况,若仍然使用 If语句就会出现多层嵌套,非常烦琐。为此 Object Pascal专门提供了 Case 语句来实现多分支选择结构。
Case 语句可以根据“选择器表达式”的值来决定执行相应的选择语句。
case <选择器表达式> of
<情况常量表 1>:<语句 1>

<情况常量表 n>:<语句 n>
[else
<其他语句列>; ]
end;
<情况常量表>中的值应当是<选择器表达式>可能具有的值,各常量之间用逗号分隔。所有常量表中的值必须互不相同。<语句>可以是简单语句也可以是复合语句。 Case 语句首先计算<选择器表达式>的值,然后判断该值是否等于某个常量,若相等则执行该常量后面的语句,执行完该语句后,跳过所有其他语句执行 end 后面的语句。若与所有情况常量表中所列的常量都不同,则执行 else 后面的语句。
3.3 循环控制结构循环是计算机解题的一个重要特征。计算机运算速度快,
最宜于做重复性工作。在程序设计时,人们也总是把复杂的不易理解的求解过程转化为易于理解的操作的多次重复。这样一方面可以降低问题的复杂性,减低程序设计难度;另一方面也发挥了计算机速度快的优势。
循环控制有两种方法:标志法与计数法。标志法是达到某一目标后使循环结束;计数法要先确定循环次数,然后逐次测试,完成测试次数后循环结束。 Object Pascal中提供了三种循环语句,Repeat语句,While语句,For语句。 Repeat
语句和 While语句采用标志法实现循环,而 For语句采用计数法实现循环。
3.3.1 Repeat 语句 (1)
Repeat 语句属于后测型循环结构。首先执行循环体,然后判断条件,根据条件决定是否继续执行循环,因此执行循环的最少次数为 1。 Repeat 语句的语句格式为:
repeat条件循环体假真
[<循环体> ]
until <条件>;
说明:<条件>是一个具有布尔值的表达式,是循环的条件。图 3-4
Repeat语句
<循环体>可以是一条语句,也可以是多条语句。
多条语句无需用 begin …end 括起来,而由保留字
repeat与 until将其括起。 Repeat循环的执行过程是:
首先执行<循环体>,然后计算<条件>的值,如果<条件>的值为假,则开始一个新循环;如果<
条件>的值为真,则终止循环,执行 until <条件>
后面的语句。可以在循环体中的任何位置放置
Break语句来强制终止 Repeat循环(随时跳出
Repeat循环)。也可以在循环体中的任何位置放置 Continue语句,在整个循环体没有执行完就重新判断<条件>,以决定是否开始新的循环。
循环体条件 假真图 3-4 Repeat语句
3.3.1 Repeat 语句 (2)
【 例 3-5】 利用公式计算 sinx。
1,主要步骤
进入 Delphi 7.0在新建窗体中添加有关组件。其中第一个编辑框用于输入数据,另一个编辑框用于数据的正弦值。如图 3-5所示。
sin x=x,..
!7!5!3 753 xxx
直到最后一项的绝对值小于 10-7为止。
图 3-5 计算 sinx的值
3.3.1 Repeat 语句 (3)
在 button1按钮的单击事件中输入如下代码:
procedure TForm1.Button1Click(Sender,TObject);
var n:integer;
x,temp,sum:double;
begin
x:=strtofloat(edit1.Text ); //从第一个编辑框中读入 x的值
n:=1;temp:=x;sum:=x;
repeat //循环语句开始
n:=n+2;
temp:=temp*(-x*x)/((n-1)*n);
sum:=sum+temp;
until abs(temp)<1e-7; //当最后一项的绝对值小于 10-7时循环语句结束
edit2.Text,=format('%f',[sum]); //输出 sinx的值
end;
3.3.1 Repeat 语句 (5)
2,分析这是一个级数求和问题,其项数决定于最后一项的绝对值是否小于
10-7,如果它大于 10-7,则计算该项,并继续求下一项,否则结束求和。
但是单独求解每一项比较麻烦,可以利用前一项求解后一项,让每一项与 n的一个值相对应,其中 n的值依次为 1,3,5,7…,从前一项求后一项只需乘以一个因子因此,只需确定当 n=1时的第一项即可,然后依次求出后一项并求和。
当然,在程序运行过程中,需要在 edit1文本框中输入数字,否则会引起错误。
3,运行结果在第一个文本框中输入一个数字后单击 button1按钮即在第二个文本框中得到答案。
nn
x
)1(
2
3.3.2 While 语句 (1)
While语句属于前测型循环结构。首先判断条件,根据条件决定是否执行循环,执行循环的最少次数为 0。 While语句的语句格式为:条件循环体假真
while <条件> do
[<循环体>= ;
说明:<条件>是判断循环的条件。<循环体>可以是简单语句、复合语句和其他结构语句。 While循环的执行过程:首先计算<条件>的值,如果<条件>的值为真,则执行 do后面的循环体,执行完后,再开始一个新的循环,如果<条件>的值为假,则终止循环,执行<循环体>后面的语句。
可以在循环体中的任何位置放置 Break语句来强制终止循环;也可以在循环体中的任何位置放置 Continue语句,在整个循环体没有执行完就重新判断<
条件>,以决定是否 开始新的循环。
【 例 3-6】 判断一个正整数是否是素数。
1,主要步骤
进入 Delphi 7.0在新建窗体中添加有关组件,其中编辑框用于输入一个整数,标签用于显示结果。如图 3-7所示。
图 3-7 判断一个正整数是否是素数
3.3.2 While 语句 (2)
在 button1按钮的单击事件中输入如下代码:
var s,n,i:integer;
str:string;
begin
n:=strtoint(edit1.Text ); //从编辑框得到 n的值,注意必须输入一个正整数
s:=0; i:=2; //s作为判断是否是素数的标志,i做除数
if n<=3 then label2.caption:='输入的整数是素数 '
else
while (i<=sqrt(n))and(s=0) do
begin
if n mod i=0 then
begin
s:=1;
break; //若以判断出 n不为素数则可以用 break语句跳出循环语句
end
else i:=i+1;
end;
3.3.2 While 语句 (3)
2,分析所谓素数是指除了 1和该数本身,不能被任何整数整除的数。如果正整数 n小于等于 3则该数是一个素数,判断一个大于 3的正整数是否是素数,只要依次用 2~作除数去除 n,若 n不能被其中任何一个数整除,则 n为素数。
3,运行结果略。
if s=0 then
label2.caption:='输入的整数是素数 '
else
label2.caption:='输入的整数不是素数 ';
end;
3.3.3 For 语句 (1)
如果不知道需要执行多少次循环,应该用 While 或 Repeat 循环。如果知道要执行多少次循环,最好用 For循环结构。 For循环与前两种循环不同,
使用一个循环变量,每重复一次循环之后,循环变量的值就会自动增加或减少。 For语句的语句格式为:
for <循环变量>,=<初值> {to | DownTo } <终值> do
[<循环体>=;
说明:<循环变量>为必要参数,用做循环计数器。<初值>和<终值>表示<循环变量>的初值和终值,可以是表达式,但应与<循环变量
> 的类型相同。若为表示式,则在进入循环之前已被计算确定,在循环体中改变初值或终值表达式中变量的值,并不影响循环的次数。 to表示计数器递增,DownTo表示计数器递减。 <循环体>可以是简单语句、复合语句和其他结构语句。 for 循环的执行过程:首先判断循环变量的值是否
“超过”终值(对于递增循环为大于,对于递减循环为小于),若已超过则跳出循环执行<循环体>后面的语句;若未超过则执行 do语句后面的<
循环体>,然后循环变量自动“增量”(递增或递减)并开始一个新的循环。可以在循环体中的任何位置放置 Break语句来强制终止循环,也可以在循环体中的任何位置放置 Continue语句,在整个循环体没有执行完就重新判断<条件>,以决定是否开始新的循环。
3.3.3 For 语句 (2)
【 例 3-7】 百钱百鸡问题。
公元前五世纪,我国古代数学家张丘建在,算经,一书中提出了“百鸡问题”:鸡翁一值钱五,鸡母一值钱三,鸡雏三值钱一。百钱买百鸡,
问鸡翁、母、雏各几何?
分析:这是一个有名的不定方程问题。
设鸡翁数为 x,鸡母数为 y,鸡雏数为 z,则可列方程如下:



1 0 0
3
35
1 0 0
zyx
zyx
对于上述不定方程问题,要先确定一个变量的值,才能对它求解。
由问题给出的条件,很容易得到三个变量的取值范围。
x,0~ 19中的整数(因为每只鸡翁 5钱,因此它不可能超过 19只);
y,0~ 33中的整数(因为每只鸡母 3钱,因此它不可能超过 33只);
z,0~ 100中的整数(因为共买百鸡,因此它不可能超过 100只)。
3.3.3 For 语句 (3)
新建一个工程,在窗体中添加一个按钮组件,在按钮的单击事件中加入如下代码。 var x,y,z:integer;
p:string;
begin
for x:=0 to 19 do
for y:=0 to 33 do
begin
z:=100-x-y;
if 5*x+3*y+z/3=100 then
begin
p:=format('得到一个解:鸡翁 %d只,鸡母 %d只,鸡雏
%d只 ',[x,y,z]);
解决该问题可以采用穷举法。穷举法是一种重复性算法。它的基本思想是对所有可能解一一测试,直到找到解或将全部可能解都测试为止。对三个未知量,依次取 x为值域中的一个值,然后求其余两个未知量,满足方程组则为该题的解。
3.3.3 For 语句 (4)
运行程序后,可以看到该程序通过一个消息窗口的形式依次将得到的解进行输出,如图 3-8 所示。
图 3-8 百钱百鸡问题
showmessage(p); //将得到的一个解用消息窗口的方式进行输出
end;
end;
end;