admin 管理员组文章数量: 1086019
2024年12月31日发(作者:agreed是什么意思)
第四单元 PASCAL语言程序设计
在上一册教材中,我们已经初步了解了PASCAL语言的三种基本结构、程序设计的基本思想
和方法。本单元是在上册内容的基础上进一步深入学习PASCAL语言的数组、子程序、字符串处
理等基础知识。随着学习的深入,程序设计的题目类型越来越广泛,难度也越来越大,程序设计
者不能“完全”把求解的任务推给计算机,而应对题目作较充分的分析,用较优的算法去求解,
因此在计算机上编程解题是一项极好的实践活动,它可以训练观察能力、逻辑思维能力、形式化
描述问题能力、规划能力、动手动脑分析问题和解决问题的能力。
第一课 循环结构的程序设计
在程序设计中,经常处理一些需要重复执行某些操作的问题,这就需要循环结构程序设计,
循环结构是程序设计的三种基本结构之一,循环结构是指当某个条件满足时反复执行某些语句,
否则不执行。利用循环结构,使得我们能用少而精的程序编码,来完成大量的重复计算。
在Pascal语言中,实现循环程序设计的主要语句有For语句(计数循环)、While语句(当型
循环)、Repeat语句(直到型循环)。上册教材已经介绍了For语句,本节课介绍While语句、Repeat
语句及多重循环结构。
一、 While语句结构
For循环语句适用于已知次数的循环结构,而在实际的问题中,有时我们并不能确切知道循
环要执行多少次,我们判断是否结束循环的依据是某个条件是否满足,比如“当„„时就做„„”,
或者是“一直做到„„时为止”,这种循环我们称之为条件循环。在Pascal中条件循环语句有两
种,分别是While循环语句和Repeat循环语句。下面分别介绍这两种语句的使用方法。
While语句用于“当满足某一条件时进行循环”的情况,因此它也被称为“当型循环”。While
语句的语法格式如下:
While <布尔表达式> do <循环体语句>;
While循环语句的执行流程如图1-1-1所示。
图1-1-1 While循环语句执行流程
布尔表达式
False
True
循环体
While语句使用说明:
(1)当布尔表达为true则执行循环体,若为false,则根本不进入循环体;
(2)如果一开始布尔表达式的值就为假时,While循环就会一次循环体都不执行;
(3)相反的,如果布尔表达式永远是真的,那么循环就无法结束,从而成为“死循环”,为
了避免这种情况的发生,在循环体中就一定要有能改变布尔表达式结果的操作;
(4)循环体中的语句一般情况下是多条语句,必须使用begin和end将它们括起来形成一条
复合语句。
[例1] 计算S=1+3+5+„„+n(n为大于1的奇数)。
程序如下:
program ex1_1;
var
odds,n,sum:integer;
begin
write(„input a odd data:‟);readln(n);
sum:=0; odds:=1;
while odds<=n do
begin
sum:=sum+odds;
odds:=odds+2;
end;
writeln(sum);
end.
[例2] 输入若干个字符,它的终止符是“?”,计算输入的字符中字母“a”出现的次数(包括
大小写)。
程序如下:
program ex1_2;
var
ch:char;
i:integer;
begin
i:=0;
read(ch);
while ch<>‟?‟ do
begin
if (ch=‟a‟) or (ch=‟A‟)
then i:=i+1;
read(ch);
end;
writeln(„i=‟,i)
end.
在执行时,每当输入的字符为“a”或“A”时,则将变量i原有的值加上1再赋给i,相当于
使i在原有的基础上加1。当输入一个“?”的时候,循环条件不成立,循环结束,输出结果。
在本程序中,输入数据“?”就是循环结束的标志,这种在程序中人为设置循环结束条件的方法
我们将它叫作结束标志法,在设计循环结构程序时经常要用到这种方法。
二、 Repeat语句结构
Repeat语句与While语句正好相反,Repeat语句用于“重复执行循环体,一直到指定的条件
为真时为止”的循环结构,它又被称为“直到型循环”。
Repeat语句的语法格式为:
repeat
循环体语句
until 布尔表达式;
Repeat循环语句的执行流程如图1-2-1所示。
Repeat语句使用说明:
1、先执行循环体,然后判断布尔表达式的值,为false,则继续循环,为true则终止循环;
2、为了使repeat循环重复能终止,与while循环一样,循环体中一定要有影响布尔表达式值
的操作,否则该循环就是一个死循环;
False
布尔表达式
True
循环体
图1-2-1 Repeat循环语句执行流程
3、repeat语句的特点是:先执行循环,后判断结束条件,因而至少要执行一次循环体;
4、repeat-until是一个整体,它是一个(构造型)语句,不要误认为repeat是一个语句,until
是另一个语句;
5、repeat循环体可以是若干个语句,不需用begin和end。
另外需要说明的是,由于while循环与repeat语句都属于条件循环语句,因此一般可以将这
两种语句互相转换,而具体使用哪条语句时要看实际情况决定。
[例3] 利用泰勒公式求e的值,直到最后一项小于10为止。泰勒公式如下:
e=1+1/1!+1/2!+1/3!+ „„+1/n!
分析:逐步往后递推,直到最后一项小于10
-7
为止。
程序如下:
program ex1-3;
var
e,p:real;
i:longint;
Begin
e:=1;p:=1;i:=1;
repeat
p:=p/i;
e:=e+p;
i:=i+1
until p<1e-7;
writeln(‘e=’,e);
end.
[例4] 求两个正整数m和n的最大公约数。
分析:求两个正整数的最大公约数采用的辗转相除法求解。以下是辗转的算法:
分别用m,n,r表示被除数、除数、余数。
①求m/n的余数r;
②若r=0,则n为最大公约数,若r≠0,执行第③步;
③将n的值放在m中,将r的值放在n中;
④返回重新执行第①步。
程序如下:
program ex1_4;
-7
var
m,n,,r : integer;
begin
write('Input m,n='); readln(m,n);
repeat
r:=m mod n;
m:=n;n:=r;
until r=0;
writeln('The greatest common divide is',m);
end.
三、多重循环结构
前面学习的循环结构都是由单一重复语句构成,即循环体部分不再是循环语句,我们把它称
之为单重循环。事实上,当一个循环体语句的循环体中包含另一个循环语句时,就构成了多重循
环,我们也称之为循环语句的嵌套结构。
由嵌套的层数分别称之为双重循环、三重循环等,处于内部的循环称为内循环,处于外部的
循环称为外循环,在循环的嵌套结构中,读者应牢牢掌握其执行过程满足“外层循环执行一次,
内层循环执行一遍”的规律。
设计多重循环时,要特别注意内、外循环之间的关系,以及各语句安放的位置,内外循环控
制变量不得同名,多重循环的执行次数为各层循环执行次数的乘积。
[例5] 用多重循环求100~999之间的所有水仙花数,所谓水仙花数,是该数等于它各位数字
的立方和,例如:153=1+3+5。
分析:根据题意,我们可以利用循环枚举三个数位上的数字,采用三重循环来求解,由于循
环次数一定,用for循环最为简单,程序如下:
program ex1_5;
var
a,b,c:integer;
begin
for a:=1 to 9 do
for b:=0 to 9 do
for c:=0 to 9 do
if a*a*a+b*b*b+c*c*c=a*100+b*10+c
then write(a*100+b*10+c:6);
333
readln
end.
[例6] 求1~100之间的素数,所谓素数,就是只能被1和它本身整除的数。
分析:要判断一个数i是否为素数,只要看i是否能被2到i-1范围内的数整除,若只要有
一个能整除i,则i不是素数,否则i为素数。因此求1~100之间的素数,只要对这个范围内的
每一个数进行判断就可以了。
程序如下:
program ex1_6;
const
n=100;
var
i,k,s:integer;
prime:Boolean;
begin
s:=0;
for i:=2 to n do {枚举n个数}
begin
prime:=true;k:=2;
while (k
begin
if i mod k=0 then prime:=false;
inc(k); {相当于k:=k+1}
end;
if prime then
begin
write(i:5);
s:=s+1;
if s mod 10=0 then writeln; {满10个就换行}
end;
end;
end.
注意:上述程序k
[例7] 编写程序在屏幕上打印出由*组成的三角形图形,其中三角形的层数n由键盘输入,如
当n=3时显示图形如下:
*
* * *
* * * * *
分析:用两层循环进行控制,外层循环控制三角形的层数,内层循环控制每一层三角形的星
号个数。
程序如下:
program ex1_7;
var
i,j,d:integer;
begin
write(„input depth:‟);readln(d);
for i:=1 to d do
begin
write(„ „:d-i+1);
for j:=1 to 2*i-1 do write(„*‟);
writeln
end;
end.
学习评价
1、从键盘读入5个数,计算它们的和与积以及平均值。
2、输入10个数,求出其中的最大值和最小值。
3、Fibnaocci(斐波那契)数列的定义如下:数列的第一项为0,第二项为1,从第三项开始,
每一项都是其前两项之和。试编程输出Fibnaocci数列的前n项元素的值。(n由键盘输入,
3<=n<=30)
4、编程求下式中n的最大值:2
2
+4
2
+6
2
+„+n
2
<1500。
5、猴子吃枣问题。猴子摘了一堆枣,第一天吃了一半,还嫌不过瘾,又吃了一个;第二天又
吃了剩下的一半零一个;以后每天如此。到第十天,猴子一看只剩下一个了。问最初有多少个枣
子?
6、要将一张100元的钞票换成等值的10元、5元、2元、1元一张的小钞票,要求每次换成
40张小钞票,每种至少一张,编程输出所有可能的换法,程序应适当考虑减少重复次数。
第二课 枚举类型和子界类型
数据是程序设计的一个重要内容,其重要特征——数据类型,确定了该数据的取值范围以及
所能参与的运算。
Pascal语言提供了丰富的数据类型,这些数据类型可以分为三大类:简单类型、构造类型和
指针类型。其中简单类型可以分为标准类型(整型、实型、字符型、布尔型)和自定义类型(枚
举类型、子界类型),构造类型可以分为数组类型、集合类型、记录类型和文件类型。这些数据类
型中除了指针类型是动态数据类型外,其他的都是静态数据类型。在这些数据类型中,除了实型
以外的简单类型都是顺序类型,所谓顺序类型就是它们的值不仅是有序的而且是有顺序号的。
枚举类型和子界类型就是本课学习的主要内容。
一、枚举类型
(一)枚举类型的定义
枚举类型是用户自定义的简单类型,适用于表示和处理一些非数值数据。例如,对于一个星
期中的每一天,一年中的四季,人的性别,交通信号灯的三种颜色等非数值数据,若用数值类型
来表示它们,比如用整数0~6分别表示星期日、星期一~星期六,用1~4分别表示春、夏、秋、
冬四季,用0和1分别表示男和女,用1~3分别表示红、绿和黄三种颜色,则显得很不直观,处
理起来也容易出错。人们希望能用直观的方式表示这些数据,而用枚举类型就能直观地表示和处
理这些数据。
枚举类型属于用户自定义类型,因此在程序的说明部分必须对类型进行定义,只有经过定义
后,这种类型才能被使用。类型说明的关键字是type,类型标识符由用户自已决定,原则是以字
母开头,后面跟以字母或数字,但注意不要使用Pascal保留字或标准标识符。如以“daytype”
表示有关日期的数据类型名,可定义如下:
type
daytype=(sun,mon,tue,wed,thu,fri,sat);
可见,枚举类型定义的一般格式为:
type
<枚举类型标识符>=(<标识符1>,<标识符2>,„„,<标识符n>);
其中,<枚举类型标识符>给出了用户定义的枚举类型的名字,括号中的<标识符1>,<标识符
2>,„„,<标识符n>称为枚举元素,它们构成了这种枚举类型的取值范围(又称“值域”),需
要注意的是<枚举类型标识符>后跟的是等号。
定义了枚举类型后,就可以在变量说明部分定义相应的枚举类型的变量了。如:
type
daytype=(sun,mon,tue,wed,thu,fri,sat);
colortype=(red,yellow,blue,white);
var
d1,d2:daytype;
c:colortype;
在类型说明部分,定义了两个枚举类型:daytype和colortype。daytype的值域为
sun,mon,tue,wed,thu,fri,sat共七个;colortype的值域为red,yellow,blue,white共四个。在
变量说明部分,定义了变量d1、d2为枚举类型daytype,它们的取值只限于类型daytype的值域,
还定义了变量c为枚举类型colortype,它的取值只限于类型colortype的值域。
初学自定义类型时应特别注意将类型名与变量名区别开来,尤其不能将类型名当作变量名使
用,类型和变量是两个完全不同的概念。例如,在上面的例子中,d1表示变量,可对其进行运算,
而daytype表示类型,不可对其施行任何运算。
以上类型定义和变量说明可合并在变量说明部分,即
var
d1,d2: (sun,mon,tue,wed,thu,fri,sat);
c: (red,yellow,blue,white);
以这样的方法说明变量的好处是较为简洁,但由于未定义类型标识符,所定义的类型不能重
复使用。
(二)枚举类型数据的特点及应用
1、枚举元素只能是标识符
枚举元素只能是标识符,不能是数值常量、字符常量等其他任何数据类型。下列的定义是错
误的:
type
monthtype=(1,2,3,4,5,6,7,8,9,10,11,12);
colortype=(‘red’, ‘yellow’, ‘blue’);
前者错在把数值常量作为枚举值,后者错在把字符串常量作为枚举值。还需注意的是,枚举
元素是标识符,但不能把作为枚举元素的标识符视作变量名,枚举值是不能被赋值的。
2、同一个枚举元素不能出现在两个或两个以上的枚举类型定义中
在一个程序中,需要定义多个枚举类型时,需注意同一个枚举元素不能出现在两个或两个以
上的枚举类型定义中。如下列的定义是错误的:
type
color1=(red,yellow,blue,white);
color2=(black,blue,green);
因为枚举元素blue既属于枚举类型color1,又属于枚举类型color2。
3、枚举类型属于顺序类型
枚举类型定义中通过列出所有值的标识符来定义一个有序集合,这些值的次序和枚举类型说
明中的标识符的次序是一致的,且序号从0开始。变量说明如下:
var
d1,d2:(sun,mon,tue,wed,thu,fri,sat);
其中枚举值sun的序号为0,枚举值mon的序号为1,依次类推,枚举值sat的序号值为6。
同时,枚举值是可以由大小来区别的,关系式sun
用序号函数可以求出枚举值的序号:
ord(sun)=0 ord(mon)=1 ord(fri)=5
用succ和pred函数可以求出枚举值的后继和前趋:
succ(sun)=mon succ(wed)=thu pred(wed)=tue pred(sat)=fri
当然,枚举类型中的第一个元素没有前趋,最后一个元素没有后继。
可见,枚举值可以作为序号函数(ord)、前趋函数(pred)和后继函数(succ)的自变量。
4、对枚举类型只能进行赋值运算和关系运算
var
d1,d2:(sun,mon,tue,wed,thu,fri,sat);
c:(red,yellow,blue,white);
此时,在程序中允许出现以下语句:
d1:=sun;
d2:=fri;
c:=blue;
if d2=d2 then write(‘the same day’) else write(‘the different day’);
可见,对枚举类型能进行赋值运算和关系运算。但下列的语句是错误的:
① mon:=1;
② c:=sun;
③ read(d1,d2,c);
④ write(d1,d2,c);writeln(blue);
错误分析:
语句①:把枚举值当成了变量名;
语句②:枚举值sun不属于枚举类型变量c的值域;
语句③:枚举类型的变量不能用read或readln语句进行读值;
语句④:枚举类型的变量值和枚举值不能通过write或writeln语句进行输出。
5、枚举类型的应用
Pascal不允许直接读写枚举值,所以枚举值的输入、输出常用case语句间接地输入、输出。
枚举值的输入,一般先读入序号,通过case语句将枚举值相应地赋给枚举变量;输出时,通过
case语句判断枚举类型变量的值,输出相应的字符串。
[例1] 有红、橙、黄、绿、蓝五种颜色的小旗,每次取出三种不同颜色的小旗表示不同的信
号,输出所有信号的方案及方案总数。
程序如下:
program ex2_1;
type
color=(red,orange,yellow,green,blue);
var
m,m1,m2,m3:color;
s,p:integer;
begin
s:=0;
for m1:=red to blue do
for m2:=red to blue do
if m1<>m2 then
for m3:=red to blue do
if (m3<>m1) and (m3<>m2) then
begin
s:=s+1;
write(s,‘:’);
for p:=1 to 3 do
begin
case p of
1:m:=m1;
2:m:=m2;
3:m:=m3;
end; {case p}
case m of
red:write(‘red’:8);
orange:write(‘orange’:8);
yellow:write(‘yellow’:8);
green:write(‘green’:8);
blue:write(‘blue’:8);
end; {case m}
end; {for p}
writeln;
end; {if}
writeln(‘total:’,s);
end.
运行后共输出60种不同的信号方案。
由于枚举类型是一种顺序类型,故枚举类型的变量可以作为循环变量。
二、子界类型
(一)子界类型的定义
在实际应用中,有些数据的变化范围只局限在某一数据类型的某一确定的区域,Pascal语言
中,对只取某一已经定义了的顺序类型的值的某一范围的这类问题,定义了子界这一数据类型。
例如,一年中的月份不超过12,一月中的天数不超过31。采用子界类型便于检查数据的合法性,
增加程序的可读性,使解决这类问题既符合常规概念,又自然清晰,更好保证了程序运行的正确
性。
子界类型定义的一般格式为:
type
<子界类型标识符>=<常量1>..<常量2>
其中常量1称作下界,常量2称作上界,且上界必须大于下界。下界和上界可以是整型、字
符型、布尔型、枚举型等顺序型的两个常量,但必须是同一种顺序类型,该顺序类型称为子界类
型的“基类型”。一个子界类型的取值范围是其基类型的取值范围中从下界到上界的连续一段,子
界类型的值域实际上就是基类型值域的一个子集。
下面的类型定义部分中定义了一个枚举类型和四个子界类型:
Const
n=150;
Type
week=(sun, mon, tue, wed, thu, fri, sat);
;
days=28..31;
letter='a'..'z';
workday=mon..fri;
其中,子界类型age可表示人的年龄,其基类型为整型,取值范围为整数0~150;子界类型
days可表示一个月的天数,其基类型也是整型,取值范围为整数28~31;子界类型letter表示
小写字母,其基类型为字符类型,取值范围为字符'a'~'z'; 子界类型workday可表示一个星期
的工作日,其基类型为枚举类型week,取值范围为类型week的五个枚举类型元素mon~fri,注
意作为类型workday的基类型,类型week必须在类型workday之前定义。
在定义子界类型时应注意,子界类型的基类型必须是顺序类型,常用整型、字符类型和枚举
类型,当用枚举类型时,该枚举类型必须先定义。特别不可用实型作为子界类型的基类型。基类
型为整型、字符类型和枚举类型的子界类型分别称为整数子界类型,字符子界类型和枚举子界类
型。
在定义了一个子界类型之后,就可说明该子界类型的变量。例如,对于如上定义的子界类型
age, days, letter和workday,可说明这些子界类型的变量如下:
Var
studentage: age;
n, m: days;
ch1, ch2, ch3: letter;
today: workday;
其中,整数子界类型变量studentage只能在0~150范围内取值,不可超出该范围,字符子
界类型变量ch1, ch2和ch3都只能在'a'~'z'范围内取值,余者类推。
在说明子界类型变量时还可先不定义相应的子界类型,直接在变量说明部分中将类型定义与
变量说明合并起来写,例如下面的变量说明是合法的:
Var
ch: 'A'..'Z';
u, v: 0..9;
其中,ch被说明为字符子界类型变量,其取值范围为大写字母字符'A'~'Z'; u和v被说
明为整数子界类型变量,只能取值数字0~9。
(二)子界类型数据的特点及应用
1、对基类型适用的各种运算,均适用于该子界类型
一个子界类型与其基类型的区别仅在于取值范围不同,前者的取值范围是后者的取值范围中
连续的一部分,除此之外,子界类型具有其基类型的所有性质。所以,子界类型的运算完全取决
于其基类型,即基类型的所有运算同样适用于其子界类型。例如,整型的运算有算术运算:+、-、
*、Div和Mod,以及关系运算和赋值运算,这些运算都适用于整数子界类型;而适用于字符子界
类型和枚举子界类型的运算为关系运算和赋值运算。
同样,适用于一个有序类型的函数运算也适用于以其为基类型的子界类型。例如,适用于枚
举子界类型的函数运算有:前趋函数Pred,后继函数Succ和序号函数Ord。由于子界类型本身也
是顺序类型,所以序号函数Ord适用于任何一个子界类型,只是子界类型每个值的序号是按该值
在相应的基类型中的序号来定的。例如,下面程序:
Program test;
Type
week=(sun, mon, tue, wed, thu, fri, sat);
Var
d: tue..fri;
n: -1..1;
c: 'A'..'Z';
Begin
d:=wed;
n:=1;
c:='A';
Writeln(Ord(d):3, Ord(n):3, Ord(c):3);
End.
的输出结果为:
3 1 65
子界类型的输入、输出方法同样与其基类型相同。例如,枚举子界类型变量的值不能用标准
过程Read和Write直接输入和输出,只可采用与枚举类型变量相同的方法间接输入和输出。
2、在同一程序中,具有相同类型的不同子界类型的数据,可以混合运算
例如,若有如下变量说明:
Var
n: Integer;
m: 0..9;
k: 5..20;
则下列赋值语句都是合法的:
n:=3;
m:=n;
k:=n*m+1;
n:=(k-m)*n;
应注意在对子界类型变量赋值时,所赋的值不要越界。
若执行下列语句:
m:=10;k:=n+50;
则变量m的值为10,变量k的值为53,均超过m,k的值域,则在编译时会出错。
3、子界类型的应用
[例2] 从键盘上输入一个字符,判断其为数字字符,字母字符还是其它字符。
程序如下:
Program ex2_2;
Var
c: Char;
Begin
Readln(c);
Case c Of
'0'..'9': Writeln('This is a digit.');
'A'..'Z', 'a'..'z': Writeln('This is a letter.');
Else Writeln('This is a other character.');
End;
End.
[例3] 确定1900~2000年中某年某月的天数。
程序如下:
Program ex2_3;
Type
year=1900..2000;
month=1..12;
days=28..31;
Var
y: year;
m: month;
d: days;
Begin
{$R+}
Write('Input year(1900-2000) and month:');
Readln(y, m);
Case m Of
1,3,5,7,8,10,12:d:=31;
4,6,9,11:d:=30;
2:If (y Mod 4=0) And (y Mod 100<>0) Or (y Mod 400=0) Then d:=29
Else d:=28;
End;
Writeln('d=',d);
End.
在该程序中定义了整数子界类型year、month和days分别表示年、月和天数,为了使系统
在运行程序时能自动检查子界类型变量y、m和d的值是否越界,在程序中加了编译器指示{$R+}。
若在运行该程序时输入越界的年份或月份,例如输入年份为2001,则中断程序的运行,并出现如
下出错信息:
range check error
学习评价
1、设有四种水果:苹果、橘子、香蕉和菠萝,现要任取其中3种水果,不能重复,不计先
后顺序,请编写程序列出所有可能的取法。
2、输入年、月、日,输出该月有几天。
3、类型定义
type ren=’A’..’F’;
用A至F表示6个人,输出6个人相互握手的各种情况,统计握手的次数。
第三课 数组
在前面我们所学的变量都是独立的变量,即变量之间没有内在的联系,一个变量只能表示一
个数据。如果处理的数据个数较少,仅使用简单变量编程就够了。如果处理大批数据,而且这些
数据之间有某种内在联系,例如,一个工厂100名工人,要给这100人记入每个月的工资,并求
月平均工资,那么用简单变量处理就很不方便了。像此处所说的求平均工资的问题,需要设100
个变量:S
1
,S
2
,┉,S
100,
要写出100个变量名,然后在求月平均工资的表达式中进行100项相
加运算;如果要处理1000个数据,就要设1000个变量,这种方法显得太烦琐了。为了便于描述、
处理,我们经常用一个变量来表示一批数据,而这类变量中,最常用的是数组。
数组是程序中最经常使用的数据类型,由固定数目的相同类型的元素按一定的顺序排列而
成。并且在Pascal语言中,数组的元素个数必须事先确定。同时,数组元素的数据类型也必须是
固定的、惟一的。比如实型数组,数组元素都必须是实型数;字符数组,数组元素都必须是字符。
一、一维数组
(一)一维数组的定义
一维数组是指只有一个下标的数组,一般用于线性批量数据的组织。
在Pascal语言中定义数组有两种方法:
(1)在说明部分type区中定义数组类型,然后再在Var区中说明数组。形式如下:
type
数组类型名=array[下标类型] of 数组元素类型;
var
数组名:数组类型名;
例如:
type
arr1=array[1..100] of real;
var
a,b:arr1;
以上说明部分的type区中,由用户定义了一个名为arr1的数组类型,在var部分说明了a
和b为arr1类型的数组。
(2)直接在var区中定义数组
var
数组名:array[下标类型] of 数组元素类型;
对于上例中a,b数组的定义,我们完全可以采用以下形式:
a,b:array[1..100] of real;
说明:其中array和of是pascal保留字。方括号中的“下标类型”可以是任何顺序类型,
即可以是整型、布尔型、字符型、枚举类型和子界类型。下标类型不仅确定了该数组中数组元素
下标的类型,也规定了数组元素可用下标的上界、下界和该数组中元素的个数。如上例:下标类
型为子界类型,它规定了数组元素下标的下界是整数1,上界是整数100,该数组一共包含100
个元素。在保留字of后面的数组元素类型规定了数组中所包含的每个元素的类型,数组元素类型
可以是任何类型。在同一个数组中,所有数组元素都具有相同类型。因此我们可以说,数组是由
固定数量的相同类型的元素组成的。
再次提请注意:类型和变量是两个不同概念,不能混淆。就数组而言,程序的执行部分使用
的不是数组类型(标识符)而是数组变量(标识符)。
(二)一维数组的引用
当定义了一个数组,则数组中的各个元素就共用一个数组名( 即该数组变量名),它们之间
是通过下标不同以示区别的。 对数组的操作归根到底就是对数组元素的操作。一维数组元素的引
用格式为:
数组名[下标表达式]
说明:①下标表达式值的类型, 必须与数组类型定义中下标类型完全一致,并且不允许超越
所定义的下标下界和上界。
②数组是一个整体,数组名是一个整体的标识,要对数组进行操作,必须对其元素操作。数
组元素可以象同类型的普通变量那样作用。如:a[3]:=34;是对数组a中第三个下标变量赋以34
的值。read(a[4]);是从键盘读入一个数到数组a第4个元素中去。
特殊地,如果两个数组类型一致,它们之间可以整个数组元素进行传送。如:
var a,b,c:array[1..100] of integer;
begin
c:=a;a:=b;b:=c;
end.
在上程序中,a,b,c三个数组类型完全一致, 它们之间可以实现整数组传送,例子中,先将
a数组所有元素的值依次传送给数组c,同样b数组传给a,数组c又传送给b,上程序段实际上
实现了a,b 两个数组所有元素的交换。
(三)一维数组的应用举例
对数组的操作其实是对所有数组元素的操作,数组元素在上下界之间是连续的,我们可以通
过逐个改变下标来逐个进行访问,而下标也可以是个变量,针对这些特点,对数组的操作往往利
用下标设计循环,以提高处理效率。
[例1] 按照顺序读入10个数据,以逆序方式输出。
分析:我们可定义一个数组a用以存放输入的10个数, 然后将数组a内容逆序输出。
程序如下:
program ex3_1;
var
a:array[1..10] of integer;
i :integer;
begin
writeln(„Input 10 dates:‟);
for i:=1 to 10 do read(a[i]);
writeln(„revers:‟);
for i:=10 downto 1 do write(a[i]:3);
end.
[例2] 编程,从数组中找出最大的一个元素,并指出它是哪一个元素。
分析:设变量max,先将第一个元素的值赋与max,从第二个元素开始逐个与max比较,如
max小于当前元素,则把当前元素的值赋于max,并记录其下标,然后按此方法,直到所有元素都
与max比较完后,max的值即是所有元素中的最大值。
程序如下:
program ex3_2;
var a:array [1..100] of integer;
i,k,n,max:integer;
begin
write('Input n:'); readln(n);
writeln('Input ',n,' datas into array:');
for i:=1 to n do read(a[i]);
readln;
max:=a[1]; k:=1;
for i:=2 to n do
if max begin max:=a[i]; k:=i end; writeln('Max is a[',k,']=',max) end. [例3] 从键盘输入若干个数,将它们按照从小到大的顺序输出。 分析:在数据处理中经常使用排序。排序的方法很多,如:选择法、冒泡法、shell排序法、 插入法等。我们这里以选择法为例如何实现排序。 选择排序的过程如下: 先将一组数(假定为整数)放在a[1],a[2],„,a[n]中。先用a[1]和其他各个元素进行比较, 凡比它小的进行交换,一直比到a[n],这样,a[1]中存放的便是最小的元素。然后用a[2]和 a[3],a[4],„,a[n]进行比较,凡比它小的进行交换,这样a[2]中存放的便是n个数中的次小元 素,以此类推,直到最后。于是a[1]~a[n]便成为一组从小到大排序的数据。 对于数组a,第一遍扫描需进行n-1次比较操作,最小数置于a[1],第二遍扫描需进行n-2 次比较操作,次小数置于a[2],每扫描一次,比较的范围就向后移动一个位置。当扫描到第n-1 次时,比较数据只需一次就能完成整个排序过程。 程序如下: program ex3_3; const n=10; {假设有10个数据需排序} var a:] of integer; i,j:integer; temp:integer; begin writeln('Input ',n,' datas into array:'); for i:=1 to n do read(a[i]); writeln(‘array a:’); for i:=1 to n do write(a[i]:3);writeln; {输出原始数据} for i:=1 to n-1 do for j:=i+1 to n do if a[i]>a[j] then begin temp:=a[i];a[i]:=a[j];a[j]:=temp; {交换a[i]、a[j]} end; writeln(‘Result’); for i:=1 to n do write(a[i]:3);writeln; {输出排序结果} end. [想一想] 如果需要将一组数据从大到小排序,程序该如何调整? [例4] 给定含有n(n<=100)个有序(不妨设为从小到大)整数的序列,现从键盘输入一个新 的整数x,将x插入到序列中,使之仍然有序。 分析:我们将n个有序序列的元素存放在一个数组a中,首先需要找到元素x的插入位置i, 然后从第i+1个元素至最后一个元素都向后移动一个位置,即a[j+1]:=a[j](i+1<=j<=n),最后我 们将元素x插入到第i个位置即可,根据这一思想,我们得到程序如下: program ex3_4; const maxn=100; var a:axn] of integer; n,x,i,j,k:integer; begin writeln(‘Input n:’);readln(n); for i:=1 to n do read(a[i]); writeln(‘Input x:’);read(x);
版权声明:本文标题:freePascal教程 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.roclinux.cn/p/1735690287a1682791.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论