本书以前章节简单地介绍了Pascal语言的数据类型,并较详细地讨论了整数类型、实数类型、字符类型和布尔类型等四种标准的数据类型。这些类型对应的常数、变量及函数的取值范围和它们所能执行的运算是由Pascal语言本身规定的(即程序员不必在程序中加以说明),因此称为标准类型。由于实际问题中出现的数据形式是多种多样的,若只局限于这四种标准类型来编写程序,将会语言的应用范围。
从本章开始,将讨论其余的数据类型。这些类型的数据,可以完全由用户自已依据Pascal语言的语法规则来确定,即进行类型定义。通过类型的定义,进一步确定它们各自的特性。
本章仅仅介绍两种用户自定义型数据类型即枚举类型和子界类型。它们都属于简单数据类型。它们所包含的数据通常被称为这种类型的元素。
第一节 枚举
通过预定义(type)列出所有值的标识符来定义一个有序集合,这些值的次序与枚举类型说明中的标识符的次序是一致的。 枚举类型的一般形式: type <类型标识符>=(标识符表);
其中括号内的标识符表是一串由逗号隔开的标识符,它列举了枚举类型所能取值的范围。例如: type
colors=(red,green,blue);
days=(sunday,monday,tuesday,wednesday,thursday,friday,saturday); 定义枚举类型时,需要注意的是:
1.枚举元素只能是标识符,而不能是数值常量或字符常量。例如下面的定义是错误的。
type
days=('sun','mon','tue','wed','thu','fri','sat'); number=(1,2,3,4,5);
2.枚举元素是标识符,不要把作为枚举元素的标识符视作变量名,它不能被赋值。 3.同一个枚举元素不能出现在两个或两个以上的枚举类型定义中。如下面的定义是错误的:
type
daytype1=(sunday,monday,tuesday);
daytype2=(wednesday,tuesday,friday,saturday,sunday);
4.枚举类型属于顺序类型。根据定义类型时各枚举元素的排列顺序确定它们的序号,序号从0开始。
例如在已定义的枚举类型days中,ord(sunday)=0、succ(sunday)=Monday、pred(monday)=sunday。
枚举类型中的第一个元素无前趋,最末一个元素无后继,如pred(sunday)或succ(saturday)是错误的。
由于枚举类型常量的有序性,常常用枚举类型变量作为for语句的控制变量。假如,已有变量说明语句 var day:days,则能使用 for day:=sunday to saturday do 语句。 case语句的表达式类型也经常使用枚举类型,而分情况常量为枚举类型的标识符。例如:
case day of
sunday: write('SUNDAY'); monday: write('MONDAY'); tuesday: write('TUESDAY'); wednesday:write('WEDNESDAY'); thursday: write('THURSDAY'); friday: write('FRIDAY'); saturday: write('SATURDAY'); end;{case}
由于标准Pascal不允许直接读写枚举值,所以枚举值的输出常用case语句构造。至于枚举值的输入,则要一一判断读入字符是否是枚举类型的标识符。若是,才能赋给枚举变量,否则会出错。
例7-1 一家水果店出售四种水果,每公斤价格是苹果1.5元,桔子1.40元,香蕉1.48元,波萝1.08元。编一个程序,使售货员只要在键盘上打入货品的代码及重量,计算机将显示货品名、单价、重量及总价。
program example7_1; const
priapple=1.50; priorange=1.40; pribanana=1.48; pripineapple=1.08; type
fruittype=(apple,orange,banana,pineapple); var
code:integer; weight:real; fruit:fruittype; begin {main} repeat
writeln('1.apple;2.orange;3.banana,pineapple'); writeln('input code and weight: '); readln(code, weight);
until (weight>0) and ((code=1) or (code=2) or (code=3) or (code=4)); case code of
1: fruit:=apple; 2: fruit:=orange; 3: fruit:=banana; 4: fruit:=pineapple; end; {case} case fruit of
apple: writeln('apple',priapple:6:2, '*', weight:6:2,'=', priapple*weight:8:2);
orange: writeln('orange',priorange:6:2,'*',weight:6:2,'=', priorange*weight:8:2);
banana:
writeln('banana',pribanana:6:2,'*',weight:6:2,'=', pribanana*weight:8:2);
pineapple:writeln('pineapple',pripineapple:6:2,'*',weight:6:2,'=',pripineapple*weight:8:2);
end {case} end. {main}
例7-2 从红、黄、兰、白、黑五个球中任取三个球,求所有可能的颜色。
program example7_2;
type colour=(red,yellow,blue,white,black); var i,j,k,pri:colour; loop,n:integer; begin n:=0;
for i:=red to black do for j:=red to black do if (i<>j) then
for k:=red to black do
if (k<>i) and (k<>j) then begin
n :=n+1; write(n:4);
for loop:=1 to 3 do begin
case loop of 1: pri:=i; 2: pri:=j; 3: pri:=k; end;{case} case pri of
red: write(' red'); yellow: write('yellow'); blue: write(' blue'); white: write(' white'); black: write(' black'); end;{case} end;{for loop} writeln; end;{if}
writeln('TOTAL NUM: ',n);
end. {main}
第二节 子界
子界类型是由整型,字符型,枚举型,布尔型的两个常量指定该类型的值域区间。 子界类型的一般形式: type <类型标识符>=<常量1>..<常量2>; 其中,常量1称为下界,常量2称为上界,它们必须属于同一个顺序类型,不能为实型。下界必须小于等于上界。例如: var
index: 1..20;
letter:'a'..'z'; digit: '0'..'9'; examscores:0..100;
一个子界类型继承它的常量类型的运算符和标准函数,常量类型相容的不同子界类型可以混合运算,可以赋值。
例如表达式examscores+digit*index是合法的;语句 examscores:=index*digit 也是正确的。然而程序执行时,若index*digit的值大于100,则会出错,因为不能给任何一个子界类型变量赋一个超出它指定界限的值。
例7-3 按月、日、年的顺序读入一个日期,输出该日期是这一年中的第几天。
program example7_3; var year: 0..2050; month,i: 1..12; day: 1..31; dayth: integer; begin {main}
readln(month,day,year); dayth:=0;
for i:=1 to month-1 do case i of
1,3,5,7,8,10,12: dayth:=dayth+31;
2 : if ((year mod 4=0) and (year mod 100<>0))•or(year mod 400=0) then dayth:=dayth+29 else dayth:=dayth+28; 4,6,9,11: dayth:=dayth+30; end; {case}
dayth:=dayth+day;
writeln(month:2,'/',day:2,'/',year:4,'=',dayth:5,'th day') end. {main}
第三节 类型相容性与赋值相容性
Pascal的一个重要优点在于它允许用户自己定义类型。但一个程序中定义的类型多了,不同类型之间就会有一系列的关系问题。 赋值运算是否可以进行取决于赋值号两边的类
型是否满足赋值相容的要求。如下面的赋值运算是非法的: Var x:1..100;
y:real; z:integer; ……
X:=101; z:=y; ……
但y:=z是合法的。下面通过介绍类型的一致性和相容性引出赋值的相容性。
一、类型的一致性
1.类型T1和T2有相同的类型标识符。 例如:
T1=integer; T2=integer;
T1和T2类型一致。
2.T1被说明成等价于T2的一个类型。 例如:
T1=integer; T2=T1;
二、类型的相容性
1.如果两个类型是同一的,则它们必相容。
2.如果一个类型是另一个类型的子界,或两个类型都是第三个类型的子界,则该两类型相容。例如: type1=1..100; type2=1..50;
type3=(sun,mon,tue,wed,thu,fri,sat); type4=(sun,mon,tue); var a: integer; b: type1; c: type2; d,e: type3; f: type4;
b和a,c和b都属类型相容,因为type1是integer的子界,又因为type1,type2都是integer的子界,a,b,c为类型相容的变量。d,e被同一类型说明,所以也相容。type4是type3的子界,f和d,e也是类型相容。
3.如果两个集合类型的基类型相容,则此两集合类型相容。例如: type s1=set of char; s2=set of 'a'..'z';
S1和S2类型相容。有关“集合”内容详见第九章。
4.如果两个字符串类型,其所含字符个数相同,则此两类相容。详见第八章。
三、赋值相容
赋值相容是指一种类型的值可以通过赋值运算赋给另一类型的变量。赋值相容是下面情况的任何一种:
1.T1和T2是一致的类型(除文件类型或含有文件分量的构造类型)。 2.T1是实型,T2是整型。即整型值可赋给实型变量。
3.T1和T2是相容的顺序类型,而且变量vt2的值在T1的值域内。 4.T1和T2是相容的集合类型,且vt2的值域包含在T1的值域内。 5.T1和T2是相容的字符串类型。
例如var vt1:real;vt2:integer;vt3:real,vt4:1..100; vt1:=vt2;{满足2} vt1:=vt3;{满足1}
vt2:=vt1;{赋值不相容} vt2:=vt4;{满足3}
第四节 枚举类型和子界类型的应用
例7-4 输入星期日至星期六的英文缩写(Sun,Mon,Tue,Wed,Thu,Fri,Sat),输出完整单词。
分析 首先定义一个包含Sun、Mon、Tue、Wed、Thu、Fri和Sat的枚举类型,利用case语句,输出任一枚举值对应的完整单词。
Program ex7_4; Var
Wd: (Sun,Mon,Tue,Wed,Thu,Fri,Sat); Begin
For wd:=Sun to Sat do Case wd of
Sun:writeln('Sunday'); Mon:writeln('Monday'); Tue:writeln('Tuesday'); Wed:writeln('Wednesday'); Thu:writeln('Thursday'); Fri:writeln('Friday'); Sat:writeln('Saturday') End End.
练 习 题
1.下面类型定义是否正确?为什么? (1) type char=(A,B,C,D);
(2) type month=('jan','feb','mar','apr') (3) type A=(A1,A2,A3)
2.编写一个程序,从键盘读入今天是星期几,输出昨天、今天、明天是星期几?
3.下述类型定义哪些有效?哪些无效?为什么?
(1) type a=10..max; (2) type b=20..20; (3) type c=5..10;
(4) type d=0..sqr(10); (5) type e=1.0..10.0; (6) type f='a'..'z'; (7) type g=a..'z'; (8) type h='1'..'z';
4.有下述变量说明:
var n:integer;m:-10..10; 下面的赋值语句是否有效?
(1) n:=m; (2) m:=n; (3) n:=abs(m);:=n+m
(4) n
因篇幅问题不能全部显示,请点此查看更多更全内容
Copyright © 2019- jqkq.cn 版权所有 赣ICP备2024042794号-4
违法及侵权请联系:TEL:199 1889 7713 E-MAIL:2724546146@qq.com
本站由北京市万商天勤律师事务所王兴未律师提供法律服务