pascal枚举子界集合及记录类型.docx

上传人:b****5 文档编号:30006777 上传时间:2023-08-04 格式:DOCX 页数:17 大小:24.86KB
下载 相关 举报
pascal枚举子界集合及记录类型.docx_第1页
第1页 / 共17页
pascal枚举子界集合及记录类型.docx_第2页
第2页 / 共17页
pascal枚举子界集合及记录类型.docx_第3页
第3页 / 共17页
pascal枚举子界集合及记录类型.docx_第4页
第4页 / 共17页
pascal枚举子界集合及记录类型.docx_第5页
第5页 / 共17页
点击查看更多>>
下载资源
资源描述

pascal枚举子界集合及记录类型.docx

《pascal枚举子界集合及记录类型.docx》由会员分享,可在线阅读,更多相关《pascal枚举子界集合及记录类型.docx(17页珍藏版)》请在冰豆网上搜索。

pascal枚举子界集合及记录类型.docx

pascal枚举子界集合及记录类型

第十一课 枚举、子界、集合及记录类型

在前面几章中我们用到了整型、实型、布尔型、字符型的数据。

以上数据类型是由pascal规定的标准数据类型,只要写integer,real,boolean,char,pascal编译系统就能识别并按这些类型来处理。

pascal还允许用户定义一些类型,这是其它一些语言所没有的,这就使得pascal使用灵活、功能丰富。

一、枚举类型

  随着计算机的不断普及,程序不仅只用于数值计算,还更广泛地用于处理非数值的数据。

例如,性别、月份、星期几、颜色、单位名、学历、职业等,都不是数值数据。

  在其它程序设计语言中,一般用一个数值来代表某一状态,这种处理方法不直观,易读性差。

如果能在程序中用自然语言中有相应含义的单词来代表某一状态,则程序就很容易阅读和理解。

也就是说,事先考虑到某一变量可能取的值,尽量用自然语言中含义清楚的单词来表示它的每一个值,这种方法称为枚举方法,用这种方法定义的类型称枚举类型。

  枚举类型是一种很有实用价值的数据类型,它是pascal一项重要创新。

  

(一)枚举类型的定义

  枚举类型是一种自定义类型,要使用枚举类型当然也要先说明枚举类型。

  枚举类型的一般格式:

   (标识符1,标识符2,…,标识符n)

  说明:

①括号中的每一个标识符都称为枚举元素或枚举常量。

     ②定义枚举类型时列出的所有枚举元素构成了这种枚举类型的值域(取值范围),也就是说,该类型的变量所有可能的取值都列出了。

  例如,下列类型定义是合法的:

  typedays=(sun,mon,tue,wed,thu,fri,sat);

  colors=(red,yellow,blue,white,black,green);

  而下列类型定义是错误的(因为枚举元素非标识符):

  typecolortype=('red','yellow','blue','white');{字符串不是标识符,不可以作为枚举值}

  numbers=(1,3,5,7,9);{数字不可作为枚举值}

  ty=(for,do,while);

week=(sun,…,sat);{枚举值须一一列出,不可用省略号代替}

fruits=(apple,orange,pear,pear);{pear不可以作为两个枚举值}

drink=(tea,milk,orage);{orage已作为fruits的一个值,不可以再作drink类型的值}

  

(二)枚举类型变量

  定义了枚举类型,就可以把某些变量说明成该类型。

如:

  varholiday,workday:

day;

   incolor:

colors;

  也可以把变量的说明与类型的定义合并在一起,如:

  varholiday,workday:

(sun,mon,tue,wed,thu,fri,sat);

   incolor:

(red,yellow,blue,white,black,green);

(三)枚举类型的性质

  ⒈枚举类型属于顺序类型

  根据定义类型时各枚举元素的排列顺序确定它们的序号,第一个枚举元素的序号为0。

例如:

设有定义:

  typedays=(sun,mon,tue,wed,thu,fri,sat);

  则:

  ord(sun)=0,ord(mon)=1,ord(sat)=6;succ(sun)=mon,succ(mon)=tue,

  succ(fri)=sat;pred(mon)=sun,pred(tue)=mon,pred(sat)=fri。

  应注意的是:

枚举类型中的第一个元素无前趋,最后一个元素无后继。

  ⒉对枚举类型只能进行赋值运算和关系运算

  一旦定义了枚举类型及这种类型的变量,则在语句部分只能对枚举类型变量赋值,或进行关系运算,不能进行算术运算和逻辑运算。

  在枚举元素比较时,实际上是对其序号的比较。

当然,赋值或比较时,应注意类型一致。

  例如,设程序有如下说明:

  typedays=(sun,mon,tue,wed,thu,fri,sat);

    colors=(red,yellow,blue,white,black,green);

  varcolor:

colors;

    weekday:

days;

  则下列比较或语句是合法的:

  weekday:

=mon;

  ifweekday=sunthenwrite('rest');

  weekday<>sun

  而下面比较或语句是不合法的:

  mon:

=weekday;

  mon:

=1;

  ifweekday=sunorsatthenwrite('rest');

  sun>red

  weekday<>color

  ⒊枚举变量的值只能用赋值语句来获得

  也就是说,不能用read(或readln)读一个枚举型的值。

同样,也不能用write(或writeln)输出一个枚举型的值。

如write(red)是非法的,会发生编译错误。

千万不要误认为,该语句的结果是输出"red"三个字符。

  但对枚举数据的输入与输出可通过间接方式进行。

输入时,一般可输入一个代码,通过程序进行转换,输出时,也只是打印出与枚举元素相对应的字符串。

这在后面的例题中将有使用示例。

  ⒋同一个枚举元素不能出现在两个或两个以上的枚举类型定义中。

  如:

  typecolor1=(red,yellow,white);

    color2=(blue,red,black);

  是不允许的,因为red属于两个枚举类型。

  (四)、枚举类型应用举例

  例1一周七天用sun,mon,tue,wed,thu,fri,sat表示,要求利用枚举类型编程:

当输入星期几的数字,能输出它的后一天是星期几(也用英文表示)。

  源程序如下:

  programex6_1;

  typeweek=(sun,mon,tue,wed,thu,fri,sat);

  var

    i:

integer;

    day,sucday:

week;

  begin

   write('Whatdateisit');readln(i);

   caseiof{根据输入i转换成枚举型}

    1:

day:

=mon;

    2:

day:

=tue;

    3:

day:

=wed;

    4:

day:

=thu;

    5:

day:

=fri;

    6:

day:

=sat;

    7:

day:

=sun;

   end;

   {计算明天sucday}

   if(day=sat)thensucday:

=sun

   elsesucday:

=succ(day);

   {输出明天是星期几}

   write('Thenextdayis');

   casesucdayof

    sun:

writeln('sunday');

    mon:

writeln('monday');

    tue:

writeln('tuesday');

    wed:

writeln('wednesay');

    thu:

writeln('thursday');

    fri:

writeln('friday');

    sat:

writeln('saturday');

   end;

   end.

  评注:

程序中变量day、sucday分别表示今天、明天。

二、子界类型

  如果我们定义一个变量i为integer类型,那么i的值在微型机系统的pascal中,使用2字节的定义表示法,取值范围为-32768~32767。

而事实上,每个程序中所用的变量的值都有一个确定的范围。

  例如,人的年龄一般不超过150,一个班级的学生不超过100人,一年中的月数不超过12,一月中的天数不超过31,等等。

  如果我们能在程序中对所用的变量的值域作具体规定的话,就便于检查出那些不合法的数据,这就能更好地保证程序运行的正确性。

而且在一定程度上还会节省内存空间。

  子界类型就很好解决如上问题。

此外,在数组的定义中,常用到子界类型,以规定数组下标的范围,上一章有关数组知识中我们已用到。

  

(一)子界类型定义

  子界类型的一般格式:

    <常量1>..<常量2>

  说明:

①其中常量1称为子界的下界,常量2称为子界的上界。

     ②下界和上界必须是同一顺序类型(该类型称为子界类型的基类型),且上界的序号必须大于下界的序号。

例如,下列说明:

  typeage=0.5..150;

   letter=0..'z';

   let1='z'..'a';

  都是错误的。

  ③可以直接在变量说明中定义子界类型。

如:

  typeletter='a'..'d';

     varch1,ch2:

letter;

  可以合并成:

  varch1,ch2:

'a'..'d';

  当然,将类型定义和变量定义分开,则更为清晰。

  

(二)子界类型数据的运算规则

  ⒈凡可使用基类型的运算规则同样适用该类型的子界类型。

  例如,可以使用整型变量的地方,也可以使用以整型为基类型的子界类型数据。

  ⒉对基类型的运算规则同样适用于该类型的子界类型。

  例如,div,mod要求参加运算的数据为整,因而也可以为整型的任何子界类型数据。

  ⒊基类型相同的不同子界类型数据可以进行混合运算。

  例如:

设有如下说明:

  type a=1..100;

     b=1.1000;

     c=1..500;

  var 

     x:

a;

     y:

b;

     t:

c;

     z:

integer;

  则下列语句也是合法的:

  Z:

=Sqr(x)+y+t;

  下列语句:

   t:

=x+y+z;

  当X+Y+Z的值在1~500范围内时是合法的,否则会出错。

  (三)子界类型应用举例

  例2利用子界类型作为情况语句标号,编一个对数字,大小写字母和特殊字符进行判别的程序。

  源程序如下:

  programcas;

  varc:

char;

  begin

   readln(c);

  casecof

   '0'..'9':

writeln('digits');

   'A'..'Z':

writeln('UPPER-CASELETTERS');

   'a'..'z':

writeln('lower-caseletters');

   eslewriteln('specialcharactors');

  end;

 end.

  例3使用子界型情况语句,当输入月、日、年(10301986),输出30Oct1986。

  源程序如下:

  programex6_3;

   varmonth:

1..12;

     date:

1..31;

     year:

1900..1999;

   begin

    write('Enterdate(mm-dd-yy):

');

    readln(month,date,year);

    write(date);

    casemonthof

     1:

write('Jan':

5);

     2:

write('Feb':

5);

     3:

write('Mar':

5);

     4:

write('Apr':

5);

     5:

write('May':

5);

     6:

write('Jun':

5);

     7:

write('Jul':

5);

     8:

write('Aug':

5);

     9:

write('Sep':

5);

     10:

write('Oct':

5);

     11:

write('Nov':

5);

     12:

write('Dec':

5);

    end;

    writeln(year:

7);

   end.

  枚举类型和子界类型均是顺序类型,在前面一章数组的定义时,实际上我们已经用到了子界类型,数组中的下标类型确切地讲可以是和枚举类型或子界类型,大多数情况下用子界类型。

  如有如下说明:

  typecolor=(red,yellow,blue,white,black);

  var

    a:

array[color]ofinteger;

    b:

array[1..100]ofcolor;

  都是允许的。

三、集合类型

  集合是由具有某些共同特征的元素构成的一个整体。

在pascal中,一个集合是由具有同一有序类型的一组数据元素所组成,这一有序类型称为该集合的基类型。

  

(一)集合类型的定义和变量的说明

  集合类型的一般形式为:

    setof<基类型>;

 说明:

①基类型可以是任意顺序类型,而不能是实型或其它构造类型。

同时,基类型的数据的序号不得超过255。

例如下列说明是合法的:

  typeletters=setof'A'..'Z';

  numbers=setof0..9;

  s1=setofchar;

  ss=(sun,mon,tue,wed,thu,fri,sat);

  s2=setofss;

  ②与其它自定义类型一样,可以将类型说明与变量说明合并在一起.如:

  typenumbers=setof0..9;

  vars:

numbers;

  与vars:

setof0..9;等价。

  

(二)集合的值

  集合的值是用"["和"]"括起来,中间为用逗号隔开的若干个集合的元素。

如:

  []空集

  [1,2,3]

  ['a','e','i','o','u']

  都是集合。

  说明:

  ①集合的值放在一对方括号中,各元素之间用逗号隔开。

  ②在集合中可以没有任何元素,这样的集合称为空集。

  ③在集合中,如果元素的值是连续的,则可用子界型的表示方法表示。

例如:

  

    [1,2,3,4,5,7,8,9,10,15]

  可以表示成:

    [1..5,7..10,15]

  ④集合的值与方括号内元素出现的次序无关。

例如,[1,5,8]和[5,1,8]的值相等。

  ⑤在集合中同一元素的重复出现对集合的值没有影响。

例如,[1,8,5,1,8]与[1,5,8]的值相等。

  ⑥每个元素可用基类型所允许的表达式来表示。

如[1,1+2,4]、[ch]、[succ(ch)]。

  (三)集合的运算

  ⒈赋值运算

  只能通过赋值语句给集合变量赋值,不能通过读语句赋值,也不能通过write(或writeln)语句直接输出集合变量的值。

  ⒉集合的并、交、差运算(∨、∧、-)

  可以对集合进行并、交、差三种运算,每种运算都只能有一个运算符、两个运算对象,所得结果仍为集合。

三种运算符分别用"+"、"*"、"-"表示。

注意它们与算术运算的区别。

  ⒊集合的关系运算

  集合可以进行相等或不相等、包含或被包含的关系运算,还能测试一个元素是否在集合中。

所用的运算符分别是:

=、<>、>=、<=、in

  它们都是二目运算,且前4个运算符的运算对象都是相容的集合类型,最后一个运算符的右边为集合,左边为与集合基类型相同的表达式。

  例4设有如下说明:

  typeweekday=(sun,mon,tue,wed,thu,fri,sat);

     week=setofweekday;

     subnum=setof1..50;

  写出下列表达式的值:

  ⑴[sun,sat]+[sun,tue,fri]

  ⑵[sun,fri]*[mon,tue]

  ⑶[wun,sat]*[sun..sat]

  ⑷[sun]-[mon,tue]

  ⑸[mon]-[mon,tue]

  ⑹[sun..sat]-[mon,sun,sat]

  ⑺[1,2,3,5]=[1,5,3,2]

  ⑻[1,2,3,4]<>[1..4]

  ⑼[1,2,3,5]>=[1..3]

  ⑽[1..5]<=[1..4]

  ⑾[1,2,3]<=[1..3]

  ⑿2in[1..10]

  答:

表达式的值分别是:

  ⑴[sun,sat,tue,fri]

  ⑵[]

  ⑶[sun,sat]

  ⑷[]

  ⑸[]

  ⑹[tue..fri]

  ⑺TRUE

  ⑻FALSE

  ⑼TRUE

  ⑽ FALSE

  ⑾TRUE

  ⑿TRUE

  例5输入一系列字符,对其中的数字字符、字母字符和其它字符分别计数。

输入'?

'后结束。

  源程序如下:

  programex10_2;

  varid,il,io:

integer;

    ch:

char;

    letter:

setofchar;

    digit:

setof'0'..'9';

  begin

    letter=['a'..'z','A'..'Z'];

    digit:

=['0'..'9'];

    id:

=0;il:

=0;io:

=0;

    repeat

    read(ch);

    ifchinletter

    thenil:

=il+1

    elseifchindigit

      thenid:

=id+1

      elseio:

=io+1;

   untilch='?

';

  writeln('letter:

',il,'digit:

',id,'Other:

',io);

  end.

四、记录类型

  在程序中对于组织和处理大批量的数据来说,数组是一种十分方便而又灵活的工具,但是数组在使用中有一个基本限制,这就是:

一个数组中的所有元素都必须具有相同的类型。

但在实际问题中可能会遇到另一类数据,它是由性质各不相同的成份组成的,即它的各个成

份可能具有不同的类型。

例如,有关一个学生的数据包含下列项目:

    学号  字符串类型

    姓名  字符串类型

    年龄  整型

    性别  字符型

    成绩  实型数组

  Pascal给我们提供了一种叫做记录的结构类型。

在一个记录中,可以包含不同类型的并且互相相关的一些数据。

  

(一)记录类型的定义

  在pascal中,记录由一组称为"域"的分量组成,每个域可以具有不同的类型。

  记录类型定义的一般形式:

  record

  <域名1>:

<类型1>;

  <域名2>:

<类型2>;

   :

:

   :

:

   <域名n>:

<类型n>;

  end;

  说明:

①域名也称域变量标识符,应符合标识符的语法规则。

在同一个记录中类型中,各个域不能取相同的名,但在不同的记录类型中,两个类型中的域名要以相同。

  ②记录类型的定义和记录变量可以合并为一个定义,如:

  typedate=record

      year:

1900..1999;

      month:

1..12;

      day:

1..31

     end;

  varx:

date;

  可以合并成:

  varx:

record

      year:

1900..1999;

      month:

1..12;

      day:

1..31

     end;

  ③对记录的操作,除了可以进行整体赋值,只能对记录的分量──域变量进行。

  ④域变量的表示方法如下:

  记录变量名.域名

  如前面定义的记录X,其3个分量分别为:

x.year,x.month,x.day。

  ⑤域变量的使用和一般的变量一样,即域变量是属于什么数据类型,便可以进行那种数据类型所允许的操作。

  

(二)记录的嵌套

  当一个记录类型的某一个域类型也是记录类型的时候,我们说发生了记录的嵌套,看下面的例子:

  例6某人事登记表可用一个记录表示,其中各项数据具有不同的类型,分别命名一个标识符。

而其中的"出生年月日"又包括三项数据,还可以用一个嵌套在内层的记录表示。

  具体定义如下:

  type sexs=(male,female);

     date=record

      year:

1900..1999;

      month:

1..12;

      day:

1..31;

     end;

  personal=record

      name:

string[15];

      sex:

sexs;

      birthdate:

date;

      home:

string[40];

     end;

  例7设计一个函数比较两个dates日期类型记录变量的迟早。

  设函数名、形参及函数类型定义为:

  AearlyB(A,B:

dates):

boolean;

  函数的形参为两个dates类型的值参数。

当函数值为true时表示日期A早于日期B,否则日期A迟于日期B或等于日期B。

显然不能对A、B两个记录变量直接进行比较,而要依具体的意义逐域处理。

  源程序如下:

  programex6_7;

  typedates=record

      year:

1900.1999;

      month:

1..12;

      day:

1..31

     end;

  varx,y:

dates;

  functionAearlyB(A,B:

dates):

boolean;

  varearln:

boolean;

  begin

   early:

=false;

   if(A.year

=true;

   if(A.year=B.year)and(A.month

   thenearly:

=true;

   if(A.year=B.year)and(A.month=B.month)and(A.day

   thenearly:

=true;

   AearlyB:

=early;

   end;{ofAearlyB}

  begin

   write('InputDATEX(mm-dd-yy):

')readln(X.month,X.day,X.year);

   write('InputDATEY(mm-dd-yy):

')readln(Y.month,Y.day,Y.year);

   ifAearlyB(X,Y)thenwriteln(DateXearly!

')elsewriteln('DateXnot   early!

');

  end.

  (三)开域语句

  在程序中对记录进行处理时,经常要引用同一记录中不同的域,每次都按6.4.1节所述的格式引用,非常乏味。

为此Pascal提供了一个with语句,可以提供引用域的简单形式。

  开域语句一般形式:

  with<记录变量名

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > PPT模板 > 自然景观

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1