Скачать презентацию 第二章 数据类型实质上是对存储器中 所存储的数据进行的抽象 它包 含了一组值的集合和一组操作 第一节 引言 1 Скачать презентацию 第二章 数据类型实质上是对存储器中 所存储的数据进行的抽象 它包 含了一组值的集合和一组操作 第一节 引言 1

17b668e9768e0ce9948afa1c77e2225a.ppt

  • Количество слайдов: 117

第二章 数据类型实质上是对存储器中 所存储的数据进行的抽象。它包 含了一组值的集合和一组操作。 第二章 数据类型实质上是对存储器中 所存储的数据进行的抽象。它包 含了一组值的集合和一组操作。

第一节 引言 1. 数据类型的作用 » 实现了数据抽象 » 使程序员从机器的具体特征中解脱 出来 » 提高了编程效率 2. 数据类型的分类 » 第一节 引言 1. 数据类型的作用 » 实现了数据抽象 » 使程序员从机器的具体特征中解脱 出来 » 提高了编程效率 2. 数据类型的分类 » 内部类型 » 自定义类型

第二节 内部类型 一. 内部类型的特点. 反映基本硬件特性 如:定点加. 在语言级, 标识共用某些操作的数据 对象的抽象表示 如:整型共用+、-、*、/ 第二节 内部类型 一. 内部类型的特点. 反映基本硬件特性 如:定点加. 在语言级, 标识共用某些操作的数据 对象的抽象表示 如:整型共用+、-、*、/

二. 内部类型的优越性 1. 基本表示的不可见性 基本位串对程序员是不可见的。 25+9=34 基本表示 00011001+00001001 结果 0010 从而具有优点:不同的程序设计风格, 可写性,可读性,可修改性。 二. 内部类型的优越性 1. 基本表示的不可见性 基本位串对程序员是不可见的。 25+9=34 基本表示 00011001+00001001 结果 0010 从而具有优点:不同的程序设计风格, 可写性,可读性,可修改性。

2. 编译时能检查变量使用的正确性 进行静态类型检查, 如非法运算, 形实 参类型匹配 2. 编译时能检查变量使用的正确性 进行静态类型检查, 如非法运算, 形实 参类型匹配

3. 编译时可以确定无二义的操作 u超载(多态)的概念: 运算符的意 义依赖于操作数的类型。如“+” 可以表示整数加或实数加 u编译时, 可拒绝混合运算, 或提供 类型转换指令 u合理地使用超载, 可以提高语言 的可读性和可用性 4. 3. 编译时可以确定无二义的操作 u超载(多态)的概念: 运算符的意 义依赖于操作数的类型。如“+” 可以表示整数加或实数加 u编译时, 可拒绝混合运算, 或提供 类型转换指令 u合理地使用超载, 可以提高语言 的可读性和可用性 4. 精度控制 可以通过数据类型显式定义数据的精度

第三节 用户定义类型 许多语言允许程序员规定 基本数据对象的聚合, 乃至聚 合的聚合 第三节 用户定义类型 许多语言允许程序员规定 基本数据对象的聚合, 乃至聚 合的聚合

1. 笛卡尔积 N个集合A 1, A 2, …, An的笛卡尔积表示为 A 1 A 2 … An,它是一个集合, 1. 笛卡尔积 N个集合A 1, A 2, …, An的笛卡尔积表示为 A 1 A 2 … An,它是一个集合, 其元素为 (a 1, a 2, …, an), ai Ai 任意正多边形可表示为 integer real

2. 有限映像 ①定义:从定义域类型DT的值的 有限集合,到值域类型RT的值的 有限集合的函数称为有限映像。 var a: array[1. . 50] of char; 表示:整数 1至 2. 有限映像 ①定义:从定义域类型DT的值的 有限集合,到值域类型RT的值的 有限集合的函数称为有限映像。 var a: array[1. . 50] of char; 表示:整数 1至 50到字符集的有限映像 ②值域对象通过下标选取。

③下标越界会出错,动态检查 ④下标可用来选取值域的多个元素 ⑤SNOBOL 4的ARRAY构造符并 不要求值域集的所有元素是同一 类型的 ③下标越界会出错,动态检查 ④下标可用来选取值域的多个元素 ⑤SNOBOL 4的ARRAY构造符并 不要求值域集的所有元素是同一 类型的

⑥DT到相应值的特定子集的绑定策略:. 编译时绑定 (静态数组). 对象建立时绑定 (执行到分程序时, 动态数组). 对象处理时绑定(对APL,子集范围可变) ⑥DT到相应值的特定子集的绑定策略:. 编译时绑定 (静态数组). 对象建立时绑定 (执行到分程序时, 动态数组). 对象处理时绑定(对APL,子集范围可变)

3. 序列 ①序列由任意多个数据项组成, 这些 数据项称为该序列的成分, 且类型相 同 ②串是序列 ③顺序文件的思想也是来自序列的概 念, 只能顺序读写 3. 序列 ①序列由任意多个数据项组成, 这些 数据项称为该序列的成分, 且类型相 同 ②串是序列 ③顺序文件的思想也是来自序列的概 念, 只能顺序读写

4. 递归 若数据类型T包含属于同一类型T的成 分,那么类型T称为递归类型。 ①允许在类型定义中使用被定义类型的名 字 ②指针是建立递归数据对象的重要手段 4. 递归 若数据类型T包含属于同一类型T的成 分,那么类型T称为递归类型。 ①允许在类型定义中使用被定义类型的名 字 ②指针是建立递归数据对象的重要手段

5. 判定或是一个选择对象结构的构造机 制, 规定在两个不同选择对象之间作出适 当的选择。每一选择对象结构称为变体。 例如:PASCAL的变体记录; C的联合。 5. 判定或是一个选择对象结构的构造机 制, 规定在两个不同选择对象之间作出适 当的选择。每一选择对象结构称为变体。 例如:PASCAL的变体记录; C的联合。

6. 幂集 类型T的元素所有子集的集合,称为 幂集, 记为Powerset(T), T称为基类型。 应用: 每次的操作对象仅仅是某个集合的 子集。 6. 幂集 类型T的元素所有子集的集合,称为 幂集, 记为Powerset(T), T称为基类型。 应用: 每次的操作对象仅仅是某个集合的 子集。

7. 小结 通过PASCAL的类型定义和变量说明,给出 用户定义类型显式命名的优点: ①可读性 ②可修改性 (选择名字) ③可分性 (不修改变量说明) (重复使用) ④一致性检查 (参考第 10节) 7. 小结 通过PASCAL的类型定义和变量说明,给出 用户定义类型显式命名的优点: ①可读性 ②可修改性 (选择名字) ③可分性 (不修改变量说明) (重复使用) ④一致性检查 (参考第 10节)

u 匿名类型 var a: record x: integer; y: array[1. . 10] of char end; u 匿名类型 var a: record x: integer; y: array[1. . 10] of char end; u 显式命名 type complex=record radius: real; angle: real end; var c 1, c 2, c 3: complex;

第四节 PASCAL类型结构 一. 非结构类型 1. 内部类型 integer, real, boolean, char 2. 有序类型 每一元素都有唯一的前驱和后继 如: 第四节 PASCAL类型结构 一. 非结构类型 1. 内部类型 integer, real, boolean, char 2. 有序类型 每一元素都有唯一的前驱和后继 如: 整型, 布尔型, 字符型 3. 定义新的有序类型的方法 » 枚举型 其值不能直接读/写 » 子界型 动态检查范围

例: type day=(sunday, monday, tuseday, wednesday, thursday, friday, saturday); work_day=monday. . friday; var class_day: 例: type day=(sunday, monday, tuseday, wednesday, thursday, friday, saturday); work_day=monday. . friday; var class_day: work_day; class_day: =succ(class_day);

二. 聚合构造 1. 数组构造 » 构造符ARRAY允许程序员定义有限映象 array[t 1] of [t 2] » PASCAL把下标类型不同的数组看成不 同的类型 二. 聚合构造 1. 数组构造 » 构造符ARRAY允许程序员定义有限映象 array[t 1] of [t 2] » PASCAL把下标类型不同的数组看成不 同的类型 type a 1=array[1. . 50] of integer; a 2=array[1. . 70] of integer;

» “符合数组”的概念(见下页) 维数相同, 成分类型相同 » PASCAL可定义多维数组 type row=array[-5. . 10] of integer; var my_matrax: » “符合数组”的概念(见下页) 维数相同, 成分类型相同 » PASCAL可定义多维数组 type row=array[-5. . 10] of integer; var my_matrax: array[3. . 30] of row; 或 var my_matrix: array[3. . 30, -5. . 10] of integer;

procedure sort(var a: array[low. . high: integer] of ctype); var i: integer; more: boolean; procedure sort(var a: array[low. . high: integer] of ctype); var i: integer; more: boolean; begin {sort} more: =true; while more do begin more: =false; for i: =low to high-1 do begin if a[i]>a[i+1] then begin move_right(i); more: =true end end {sort};

2. 记录构造 ①构造符RECORD用以定义笛卡尔积 ②记录可以整体访问,也可用圆点 “. ” 作为选择符访问单个的域 ③PASCAL的变体记录 2. 记录构造 ①构造符RECORD用以定义笛卡尔积 ②记录可以整体访问,也可用圆点 “. ” 作为选择符访问单个的域 ③PASCAL的变体记录

type dept=(house, sports, drugs, food, liquor); month=1. . 12; item=record price: real; case available: type dept=(house, sports, drugs, food, liquor); month=1. . 12; item=record price: real; case available: boolean of true: (amount: integer; where: dept); false: (month_expected: month) end;

var i 1, i 2: item: …… i 1. price: =5. 24; i 1. var i 1, i 2: item: …… i 1. price: =5. 24; i 1. available: =true; i 1. amount: =29; i 1. where: =liquor; i 2. price: =324. 99; i 2. available: =false; i 2. month_expect: =8;

price available amount where 5. 24 true 29 liquor price available month_expected 324. 99 price available amount where 5. 24 true 29 liquor price available month_expected 324. 99 false 8

④使用变体记录不安全 ■可以对变体赋值 ■可以改变标识符域 ■标识符域的标识符可省缺 ④使用变体记录不安全 ■可以对变体赋值 ■可以改变标识符域 ■标识符域的标识符可省缺

3. 集合构造 » SET构造符是幂集构造受限制的形式 » 基类型只能是有序类型 type vegetable=(bean, cabbage, carrot, celery, lettuce, onion, mushroom, 3. 集合构造 » SET构造符是幂集构造受限制的形式 » 基类型只能是有序类型 type vegetable=(bean, cabbage, carrot, celery, lettuce, onion, mushroom, zucchizi); var my_salad, leftover: set of vegetable;

4. 文件构造 » PASCAL文件是任意类型的诸元素的 序列 type pattern=record …end; tape=file of pattern; var t 1, 4. 文件构造 » PASCAL文件是任意类型的诸元素的 序列 type pattern=record …end; tape=file of pattern; var t 1, t 2: tape; » PASCAL文件仅能顺序处理 » PUT和GET操作

三. 指针 » 指针可引用匿名数据对象 NEW, 堆 » 空指针的使用 » 指针的操作: 赋值, 比较 » PASCAL指针只能指向匿名数据对象 三. 指针 » 指针可引用匿名数据对象 NEW, 堆 » 空指针的使用 » 指针的操作: 赋值, 比较 » PASCAL指针只能指向匿名数据对象

指针例子 type tree_ref= binary_tree_node; binary_tree_node=record info: char; left, right: tree_ref end; pointer= node; node=record 指针例子 type tree_ref= binary_tree_node; binary_tree_node=record info: char; left, right: tree_ref end; pointer= node; node=record data: integer; next: pointer end;

四. 小结. (P 37图 2 -4) 四. 小结. (P 37图 2 -4)

Pascal类型 非结构类型 指针类型 (递归) 内部类型 子界类型 整型 实型 字符型 枚举类型 布尔型 结构类型 记录类型 数组 Pascal类型 非结构类型 指针类型 (递归) 内部类型 子界类型 整型 实型 字符型 枚举类型 布尔型 结构类型 记录类型 数组 集合 文件 (迪卡尔积) 变体记录 (判定或)

第五节 Ada类型结构 一. 标量类型 1. 分类 实型 数字类型 标量类型 整型 离散类型 枚举类型 2. 标量类型的值的集合是有序的, 第五节 Ada类型结构 一. 标量类型 1. 分类 实型 数字类型 标量类型 整型 离散类型 枚举类型 2. 标量类型的值的集合是有序的, 允 许关系运算

3. 用户自定义类型 type TWO_DIGIT is range 0. . 99; FLOAT_1 is digits 10 range 3. 用户自定义类型 type TWO_DIGIT is range 0. . 99; FLOAT_1 is digits 10 range 0. 0. . 3. 0; FIT_PT is delta 0. 01 range 0. 00. . 100. 01; BOOLEAN is (FALSE, TRUE);

二. 组合类型 1. 数组 ①约束数组类型 下标界是静态确定的 type MONTH is (JAN, FEB, MAR, APR, MAY, 二. 组合类型 1. 数组 ①约束数组类型 下标界是静态确定的 type MONTH is (JAN, FEB, MAR, APR, MAY, JUN, JUL, AUG, SEP, OCT, NOV, DEC); type YEARLY_PAY is array(MONTH) of INTEGER; type SUMMER_PAY is array(MONTH range JUL. . SEP) of INTEGER;

②非约束数组类型 Ada支持动态数组 type SOME_PERIOD_PAY ia array(MONTH range< >) of INTEGER; type INT_VERTOR ia array(INTEGER ②非约束数组类型 Ada支持动态数组 type SOME_PERIOD_PAY ia array(MONTH range< >) of INTEGER; type INT_VERTOR ia array(INTEGER range < >) of INTEGER; type BOOL_MAXTRIX is array(INTEGER range < >, INTEGER range < >) of BOOLEAN; ③Ada数组类型由分量的类型, 下标个 数和下标类型来刻画

④界的确定可在数据对象成为实体时, 或参数传递时完成 SPRING_MONTH: SOME_PERIOD_PAY(APR. . JUN); Z: INT_VECTOR(-100. . 100); W: INT_VECTOR(20. . 40); ④界的确定可在数据对象成为实体时, 或参数传递时完成 SPRING_MONTH: SOME_PERIOD_PAY(APR. . JUN); Z: INT_VECTOR(-100. . 100); W: INT_VECTOR(20. . 40); Y: BOOL_MAXTRIX(0. . N, 0. . M); 其中, 界的值不一定静态给出

function SUM(X: INT-VECTOR) return INTEGER; RESULT: INTEGER: =0; begin for I in X’FIRST. . function SUM(X: INT-VECTOR) return INTEGER; RESULT: INTEGER: =0; begin for I in X’FIRST. . X’LAST loop RESULT: = RESULT+X(I); end loop; return RESULT; end SUM; 可用不同大小的数组作为实参来调用该函数 A: =SUM(Z)+SUM(W);

⑤可以在过程的局部说明中说明一个 数组, 它的界依赖于一个参数 TEMPORARY: INT_VECTOR(X’FIRST. . X’LAST); ⑤可以在过程的局部说明中说明一个 数组, 它的界依赖于一个参数 TEMPORARY: INT_VECTOR(X’FIRST. . X’LAST);

⑥切片: 用以选取一维数组若干个相 继分量 LINE: STRING(1. . 80); LINE(1. . 11): =(‘D’, ’e’, ’a’, ’r’, ⑥切片: 用以选取一维数组若干个相 继分量 LINE: STRING(1. . 80); LINE(1. . 11): =(‘D’, ’e’, ’a’, ’r’, ’f’, ’r’, ’i’, ’e’, ’n’, ’d’);

2. 记录 ①说明形式 type COORDINATE is record X: INTEGER range 0. . 100; Y: 2. 记录 ①说明形式 type COORDINATE is record X: INTEGER range 0. . 100; Y: CHARACTER; end record;

②Ada的判全或是安全的 type DEPT is (HOUSEWARE, SPORTS, DRUGS, FOOD, LIQUOR); type MONTH is range 1. ②Ada的判全或是安全的 type DEPT is (HOUSEWARE, SPORTS, DRUGS, FOOD, LIQUOR); type MONTH is range 1. . 12; type ITEM (AVAILABLE: BOOLEAN: =TRUE) is record PRICE: REAL; case AVAILABLE of when TRUE=>AMOUNT: INTEGER; WHERE: DEPT; when FALSE=>MONTH_EXPECTED: MONTH end case; end record;

判定或可具有缺省初值 也可以说明一个对象的变体是冻结的 单独对判定或赋值是不允许的 PEACH: ITEM; ORANGE: ITEM(FALSE); COCA_COLA: ITEM; COCA_COAL: =ORANGE; (合法) COCA_COAL: =(PRICE=>1. 判定或可具有缺省初值 也可以说明一个对象的变体是冻结的 单独对判定或赋值是不允许的 PEACH: ITEM; ORANGE: ITEM(FALSE); COCA_COLA: ITEM; COCA_COAL: =ORANGE; (合法) COCA_COAL: =(PRICE=>1. 99, AVAILABLE=>TRUE, AMOUNT=>1500, WHERE=>FOOD);

type dept=(house, sports, drugs, food, liquor); month=1. . 12; item=record price: real; case available: type dept=(house, sports, drugs, food, liquor); month=1. . 12; item=record price: real; case available: boolean of true: (amount: integer; where: dept); false: (month_expected: month) end;

var i 1, i 2: item: …… i 1. price: =5. 24; i 1. var i 1, i 2: item: …… i 1. price: =5. 24; i 1. available: =true; i 1. amount: =29; i 1. where: =liquor; i 2. price: =324. 99; i 2. available: =false; i 2. month_expect: =8;

price available amount where 5. 24 true 29 liquor price available month_expected 324. 99 price available amount where 5. 24 true 29 liquor price available month_expected 324. 99 false 8

3. 访问类型 ①不完全类型说明 应用于Ada的递归类型 type BINARY_TREE_NODE; type TREE_REF is access BINARY_TREE_NODE; type BINARY_TREE_NODE is 3. 访问类型 ①不完全类型说明 应用于Ada的递归类型 type BINARY_TREE_NODE; type TREE_REF is access BINARY_TREE_NODE; type BINARY_TREE_NODE is record INFO: CHARACTER; LEFT, RIGHT: TREE_REF; end; ②P. all代表整个结点

4. 子类型和派生类型 ①可以通过子类型来规定类型的一个特性 type FLAVOR is (CHOCOLATE, MINT, PEATH, STRAWBERRY, VANILLA, BLUECHEESE, CATSUP, GARLIC, 4. 子类型和派生类型 ①可以通过子类型来规定类型的一个特性 type FLAVOR is (CHOCOLATE, MINT, PEATH, STRAWBERRY, VANILLA, BLUECHEESE, CATSUP, GARLIC, ONION); subtype ICE_CREAM_FLAVOR is range CHOCOLATE. . VANILLA; subtype SMALL_INT is INTEGER range -10. . 10; subtype SMALL_POS_INTEGER is INTEGER range 1. . 10; subtype MY_INT_SET is INTEGER range A. . B; ②子类型继承基类型的所有特性, 还满足某个约束

③子类型机制也可以用来约束数组类型 (类似于给出实例) type MY_ORDERS is array(INTEGER range< >) of ICE_CREAM_FLAVOR; subtype MONTHLY_ORDERS is MY_ORDERS(1. ③子类型机制也可以用来约束数组类型 (类似于给出实例) type MY_ORDERS is array(INTEGER range< >) of ICE_CREAM_FLAVOR; subtype MONTHLY_ORDERS is MY_ORDERS(1. . 31); subtype ANNUAL_ORDERS is MY_ORDERS(1. . 365); ④也可以使用子类型来冻结判定或类型的变量 subtype OUT_OF_STOCK is ITEM(FALSE); ⑤子类型机制并未定义新类型

⑥派生类型定义新类型, 这些新类型继承了 母体类型的所有特性 type <新类型> is new <母体类型> [<约束>] type POSITIVE is 1. . ⑥派生类型定义新类型, 这些新类型继承了 母体类型的所有特性 type <新类型> is new <母体类型> [<约束>] type POSITIVE is 1. . INTEGER’LAST; type WEIGHT is new POSITIVE range 1. . 100; type LENGTH is new POSITIVE;

5. 属性 Ada 的属性用来指定数据对象、类型的 特性。 如: INTEGER’LAST 5. 属性 Ada 的属性用来指定数据对象、类型的 特性。 如: INTEGER’LAST

三. Ada数据类型小结 Ada类型 标量类型 数值类型 预定义类型 整型 实型 组合类型 枚举类型 用户定义类型 数组类型 访问类型 (递归) 三. Ada数据类型小结 Ada类型 标量类型 数值类型 预定义类型 整型 实型 组合类型 枚举类型 用户定义类型 数组类型 访问类型 (递归) 预定义类型 字符型 布尔型 记录类型 用户定义类型

第六节 C类型结构 一. 非结构类型 1. 内部类型 u u 整型分为基本型、短整型、长整型和无符号 型 实型又称为浮点型,其值是实数集合的一个 子集 字符型数据的值是一个有限字符集的元素 没有布尔型: 第六节 C类型结构 一. 非结构类型 1. 内部类型 u u 整型分为基本型、短整型、长整型和无符号 型 实型又称为浮点型,其值是实数集合的一个 子集 字符型数据的值是一个有限字符集的元素 没有布尔型: 0表示false,非 0表示true

2. 用户定义类型 u 枚举类型实例 enum bool{false,true}; 或 typedef enum{false,true} bool; u enum默认元素从0开始对应,但可以显示改 变顺序 typedef 2. 用户定义类型 u 枚举类型实例 enum bool{false,true}; 或 typedef enum{false,true} bool; u enum默认元素从0开始对应,但可以显示改 变顺序 typedef enum{false=1,true=2}badbool; 或 typedef enum{false=1,true=1}verybadbool;

二. 聚合构造 1. 数组 u 数组构造实现有限映像 intarr[5]; u 下标从0开始 u 二维数组按行存放 float farr[3][4] u 二. 聚合构造 1. 数组 u 数组构造实现有限映像 intarr[5]; u 下标从0开始 u 二维数组按行存放 float farr[3][4] u 可以定义多维数组 u 对数组名的处理相当于指针

例子: int a[10]; int *pa; pa=a; 或 pa=&a[0]; 例子: int a[10]; int *pa; pa=a; 或 pa=&a[0];

2. 结构 u 构造符struct支持迪卡尔积 struct student { int num; char name[20]; char sex; int 2. 结构 u 构造符struct支持迪卡尔积 struct student { int num; char name[20]; char sex; int age; float score; char addr[30]; };

u 结构体变量不能整体赋值和输出,只能 对其中的各个成分分别进行操作 u 可以把一个结构体变量赋值给另一个结 构体变量 u 内存中,结构体各个成员变量依次存储 u C的结构体可以嵌套使用 u 结构体变量不能整体赋值和输出,只能 对其中的各个成分分别进行操作 u 可以把一个结构体变量赋值给另一个结 构体变量 u 内存中,结构体各个成员变量依次存储 u C的结构体可以嵌套使用

3. 联合 u C语言的构造符union(联合)支持判定或 u 联合把不同类型的变量存放在同一(段)内存 单元中 u C的联合是不安全的 union data { int i 3. 联合 u C语言的构造符union(联合)支持判定或 u 联合把不同类型的变量存放在同一(段)内存 单元中 u C的联合是不安全的 union data { int i char c; float f; }

4. 文件 u C语言把文件看成一个字符序列 u 文件是由一个个字符(字节)数据顺序 组成的 u 文件FILE是由语言预定义的 u 有丰富的文件操作 4. 文件 u C语言把文件看成一个字符序列 u 文件是由一个个字符(字节)数据顺序 组成的 u 文件FILE是由语言预定义的 u 有丰富的文件操作

三. 指针 u 指针是非结构的,可用来构造结构数据, 支持递归 u 没有空指针,可以对指针赋0值表示空 u 指针用来定义递归类型的数据 三. 指针 u 指针是非结构的,可用来构造结构数据, 支持递归 u 没有空指针,可以对指针赋0值表示空 u 指针用来定义递归类型的数据

四. 空类型 u void称为空类型,是非结构的 u 返回值为空类型void表示该函数不返回 函数值 u void指针不确定指向的类型 四. 空类型 u void称为空类型,是非结构的 u 返回值为空类型void表示该函数不返回 函数值 u void指针不确定指向的类型

五. C数据类型小结 C类型 空类型 非结构型 指针类型 内部类型 枚举类型 数组类型 结构类型 整型 实型 联合类型 文件 五. C数据类型小结 C类型 空类型 非结构型 指针类型 内部类型 枚举类型 数组类型 结构类型 整型 实型 联合类型 文件 字符型 C语言没有集合! 单精度型 双精度型

第七节 抽象数据类型 1. 用户定义类型与内部类型的异同 ①都建立某种基本表示的抽象 如: integer是位串的抽象; reg_polygon是记录的抽象 ②每一类型都关联一组操作 ③内部类型隐蔽了基本表示,不能对 它的成分进行操作; 用户定义类型具 有更高级别的抽象,可以对其基本 表示的成分进行操作。 第七节 抽象数据类型 1. 用户定义类型与内部类型的异同 ①都建立某种基本表示的抽象 如: integer是位串的抽象; reg_polygon是记录的抽象 ②每一类型都关联一组操作 ③内部类型隐蔽了基本表示,不能对 它的成分进行操作; 用户定义类型具 有更高级别的抽象,可以对其基本 表示的成分进行操作。

2. 抽象数据类型的定义 满足下述特性的用户定义类型称为抽 象数据类型: 象数据类型 ①在实现该类型的程序单元中, 建立与 表示有关的基本操作; ②对使用该类型的程序单元来说, 该类 型的表示是隐蔽的。 2. 抽象数据类型的定义 满足下述特性的用户定义类型称为抽 象数据类型: 象数据类型 ①在实现该类型的程序单元中, 建立与 表示有关的基本操作; ②对使用该类型的程序单元来说, 该类 型的表示是隐蔽的。

一. SIMULA 67的类机制 1. 类的说明 <类头>; <类体> <类头>包括类名和形式参数 <类体>是传统的分程序, 可包含变量、过程 和类的局部说明,以及一些执行语句 例:复数表示(幅角, 半径) 一. SIMULA 67的类机制 1. 类的说明 <类头>; <类体> <类头>包括类名和形式参数 <类体>是传统的分程序, 可包含变量、过程 和类的局部说明,以及一些执行语句 例:复数表示(幅角, 半径)

class complex(x,y);real x,y; begin real angle,radius; radius:=sqrt(x**2+y**2); if abs(x)<epsilon then begin if abs(y)<epsilon then class complex(x,y);real x,y; begin real angle,radius; radius:=sqrt(x**2+y**2); if abs(x)epsilon then angle: =pi/2 else angle: =3*pi/2 end else angle: =arctan(y/x) end complex

2. 类的有关性质 ①类说明定义了一类数据对象的原型 或样板 ②类的每个实例是一个可操作的数据 对象 ③类的实例可多次动态建立, 且仅能通 过指针引用 例: ref(complex) c; c: - 2. 类的有关性质 ①类说明定义了一类数据对象的原型 或样板 ②类的每个实例是一个可操作的数据 对象 ③类的实例可多次动态建立, 且仅能通 过指针引用 例: ref(complex) c; c: - new complex(1. 0, 1. 0);

c 0. 78 angle 1. 42 radius 1. 0 x 1. 0 y c 0. 78 angle 1. 42 radius 1. 0 x 1. 0 y

④类实例的属性是指类体的 局 部 变 量 和类头中的参数 my_angle: =c. angle; my_radius: =c. radius; my_x: =c. ④类实例的属性是指类体的 局 部 变 量 和类头中的参数 my_angle: =c. angle; my_radius: =c. radius; my_x: =c. x; my_y: =c. y;

⑤类支持抽象数据类型的封装机制, 它 可以封装实现对数据操作的各种过程 例: 可将复数加和乘的过程add和multiply封 装入类complex的类体说明中, 作为 complex的属性。 procedure add(operand); ref (complex) operand procedure ⑤类支持抽象数据类型的封装机制, 它 可以封装实现对数据操作的各种过程 例: 可将复数加和乘的过程add和multiply封 装入类complex的类体说明中, 作为 complex的属性。 procedure add(operand); ref (complex) operand procedure multiply(operand); ref (complex) operand 变量c 1、c 2引用的两个复数相加可表示为: c 1. add(c 2)

或 c 3. angle: =c 1. angle; c 3. radius: =c 1. radius+c 2. 或 c 3. angle: =c 1. angle; c 3. radius: =c 1. radius+c 2. radius; 用户可以直接访问复数的内部表示, 故add 和multiply不是复数对象的唯一操作

3. 子类 用以定义类型的判定或和类属。 要求:定义一个栈,完成 u 引用栈顶元素 u 入栈 u 出栈 u 判栈是否空 (这些操作与栈中元素的类型无关) 3. 子类 用以定义类型的判定或和类属。 要求:定义一个栈,完成 u 引用栈顶元素 u 入栈 u 出栈 u 判栈是否空 (这些操作与栈中元素的类型无关)

栈内成员的元素类 class stack_member; begin ref (stack_member) next_member; next_member: -none end 指针型局部变量 栈内成员的元素类 class stack_member; begin ref (stack_member) next_member; next_member: -none end 指针型局部变量

class stack; begin ref (stack_member) first; ref (stack_member) procedure top; top: -first; procedure pop; class stack; begin ref (stack_member) first; ref (stack_member) procedure top; top: -first; procedure pop; if ¬empty then first: -first. next_member; procedure push(e); ref (stack_member) e; begin if first =/=none then e. next_member: -first; first: -e end push; boolean procedure empty; empty: =first= =none; first: -none end stack

加在类说明之前 stack_member class complex(……); …… end complex 定义了一个复数栈 其中complex称为stack_member的子类 加在类说明之前 stack_member class complex(……); …… end complex 定义了一个复数栈 其中complex称为stack_member的子类

①子类complex具有自己的属性, 同时 继承了stack_member的属性 new complex 产生的对象具有stack_member和complex的 所有属性 ref(stack) s; 建立一个复数栈 s: -new stack; s. ①子类complex具有自己的属性, 同时 继承了stack_member的属性 new complex 产生的对象具有stack_member和complex的 所有属性 ref(stack) s; 建立一个复数栈 s: -new stack; s. push(c 1); s. push(c 2); s. push(c 3);

②具有ref(stack_member)的变量可引用 多种类型的量, 但不同类型的元素不得压 入同一栈实例中 下述语句说明向量也可是栈中元素: stack_member class vector(…); …… end vector ②具有ref(stack_member)的变量可引用 多种类型的量, 但不同类型的元素不得压 入同一栈实例中 下述语句说明向量也可是栈中元素: stack_member class vector(…); …… end vector

二. CLU的抽象数据类型 例: 定义复数完成: 建立、加、判等 二. CLU的抽象数据类型 例: 定义复数完成: 建立、加、判等

complex=cluster is create, add, equal rep=record[x, y: real] create=proc(a, b: real) returns(cvt) return(rep $ complex=cluster is create, add, equal rep=record[x, y: real] create=proc(a, b: real) returns(cvt) return(rep $ {x: a, y: b}) end create add=proc(a, b: cvt) returns(cvt) return(rep $ {x: a. x+b. x, y: a. y+b. y}) end add equal=proc(a, b: cvt) returns(bool) return(a. x=b. x and a. y=b. y) end equal end complex

1. 簇(Cluster)是CLU用来定义抽象数据 类型的机制 ①簇内, 需要内部表示 ②簇外, 看到的是抽象表示 rep说明数据对象的具体表示 cvt用于抽象表示和具体表示之间的相互转 换, 仅能在簇内使用 return(rep $ …)的含义为返回一个具体表示 1. 簇(Cluster)是CLU用来定义抽象数据 类型的机制 ①簇内, 需要内部表示 ②簇外, 看到的是抽象表示 rep说明数据对象的具体表示 cvt用于抽象表示和具体表示之间的相互转 换, 仅能在簇内使用 return(rep $ …)的含义为返回一个具体表示 类型的对象

2. CLU的性质 ①CLU变量的作用域和生存期互不相干 P: complex 仅仅是一个说明 而P: =complex $ create(h, k)才产生一个对象赋 于P ②CLU变量被一致看成是对数据对象的引用 如 2. CLU的性质 ①CLU变量的作用域和生存期互不相干 P: complex 仅仅是一个说明 而P: =complex $ create(h, k)才产生一个对象赋 于P ②CLU变量被一致看成是对数据对象的引用 如 x: =e /* 将e的地址赋给x */ 其中x类似于指针变量 ③CLU的参数传递由赋值定义 complex $ add(x, y) 把x和y分别赋予形式参数a和b

三. Ada的抽象数据类型 1. Ada用程序包描述抽象数据类型 程序包包括规格说明和程序包体 2. “移出”的概念 这是程序包向外部世界提供的可以访问的实 体,是程序包的可见部分 三. Ada的抽象数据类型 1. Ada用程序包描述抽象数据类型 程序包包括规格说明和程序包体 2. “移出”的概念 这是程序包向外部世界提供的可以访问的实 体,是程序包的可见部分

3. 私有类型 ①私有类型的表示细节在程序包外是不 可见的 ②允许的操作: 移出的子程序、函数; 赋值、相等、不等 3. 私有类型 ①私有类型的表示细节在程序包外是不 可见的 ②允许的操作: 移出的子程序、函数; 赋值、相等、不等

package COMPLEX-NUMBERS is type COMPLEX is private; procedure INITIALIZE(A, B: in REAL; X: out package COMPLEX-NUMBERS is type COMPLEX is private; procedure INITIALIZE(A, B: in REAL; X: out COMPLEX); function ADD(A, B: in COMPLEX) return COMPLEX; private type COMPLEX is record R, I: REAL; end record; end COMPLEX-NUMBERS;

package body COMPLEX-NUMBER is procedure INITIALIZE(A, B: in REAL; X: out COMPLEX) is begin package body COMPLEX-NUMBER is procedure INITIALIZE(A, B: in REAL; X: out COMPLEX) is begin X. R: =A; X. I: =B; end INITIALIZE; function ADD(A, B: in COMPLEX) return COMPLEX is TEMP: COMPLEX; begin TEMP. R: =A. R+B. R; TEMP. I: =A. I+B. I; return TEMP; end ADD; end COMPLEX-NUMBER;

4. 受限私有类型 只允许程序包移出的子程序和函数, 不 允许赋值、相等和不相等 5. 类属的描述 使用generic子句说明类型是一个参数, 实例化时代以具体的类型 例: package INTEGERS is new 4. 受限私有类型 只允许程序包移出的子程序和函数, 不 允许赋值、相等和不相等 5. 类属的描述 使用generic子句说明类型是一个参数, 实例化时代以具体的类型 例: package INTEGERS is new SET-MANIPULATION(INTEGER); package FLAVORS is new SET-MANIPULATION(FLAVOR);

generic type COMPONENT is private; package SET-MANIPULATION is type SET is limited private; procedure generic type COMPONENT is private; package SET-MANIPULATION is type SET is limited private; procedure INSERT(S: out SET; ELEM: in COMPONENT); procedure DELETE(S: out SET; ELEM: in COMPONENT); procedure IS-IN(S: in SET; ELEM: in COMPONENT) return BOOLEAN; private type SET is record STORE: array(1. . MAX-CARDINALITY) of COMPONENT; CARDINALITY: INTEGER range 0. . MAX- CARDINALITY : =0; end record; end SET-MANIPULATION;

四. Modula-2的抽象数据类型 1. 移入(Inport)和移出(Export)子句说明模块的 移入和移出实体 2. Modula-2 的模块可以封装一组相关子程序 3. 抽象数据类型的描述由定义模块和实现模块 定义模块 两部分组成 4. Modula-2的模块可以移出类型,类型的细节 四. Modula-2的抽象数据类型 1. 移入(Inport)和移出(Export)子句说明模块的 移入和移出实体 2. Modula-2 的模块可以封装一组相关子程序 3. 抽象数据类型的描述由定义模块和实现模块 定义模块 两部分组成 4. Modula-2的模块可以移出类型,类型的细节 可通过“不透明移出”加以屏蔽

definition module Complex. Number; export qualified Complex, Initialize, Add; type Complex; /* 不透明移出 */ definition module Complex. Number; export qualified Complex, Initialize, Add; type Complex; /* 不透明移出 */ Procedure Initialize(A, B: real; var x: Complex); Procedure Add(A, B: Complex): Complex end Complex. Number.

implementation module Complex. Number; type C=record R, I: real end; type Complex=pointer to C; implementation module Complex. Number; type C=record R, I: real end; type Complex=pointer to C; procedure Initialize(A, B: real; var x: Complex); begin new(x); x. R: =A; x. I: =B end Initialize;

procedure Add(A, B: Complex): Complex; var T: Complex; begin new(T); T. R: =A. R+B. procedure Add(A, B: Complex): Complex; var T: Complex; begin new(T); T. R: =A. R+B. R; T. I: =A. I+B. I; return(T) end Add end Complex. Number.

五. C++的抽象数据类型 u 类支持封装、继承和信息隐蔽 u 类定义的一般形式: class <类名> { private: 私有段数据定义; 私有段函数定义; protected: 保护段数据定义; 五. C++的抽象数据类型 u 类支持封装、继承和信息隐蔽 u 类定义的一般形式: class <类名> { private: 私有段数据定义; 私有段函数定义; protected: 保护段数据定义; 保护段函数定义; public: 公有段数据定义; 公有段函数定义; }

u 被封装和隐蔽的部分包括私有段函数名、私有 段数据、私有段实现、保护段和公有段的实现, 这些在类外是不可见的 u 类外可见部分是公有段的函数和数据 u 类的实例是对象,对象继承了类中的数据和方 法(操作) u 多态:一个函数名可以标识多种不同的函数 u C++的继承性是通过派生类来实现的(P 60) u 被封装和隐蔽的部分包括私有段函数名、私有 段数据、私有段实现、保护段和公有段的实现, 这些在类外是不可见的 u 类外可见部分是公有段的函数和数据 u 类的实例是对象,对象继承了类中的数据和方 法(操作) u 多态:一个函数名可以标识多种不同的函数 u C++的继承性是通过派生类来实现的(P 60)

第八节 类型检查 1. 类型检查 对数据对象的类型和使用的操作是否匹配的一 致性检查称为类型检查 2. 静态检查和动态检查 ①静态检查使程序更正确更有效 ②动态检查使编程方便, 但影响了可读性, 且 降低了执行效率 第八节 类型检查 1. 类型检查 对数据对象的类型和使用的操作是否匹配的一 致性检查称为类型检查 2. 静态检查和动态检查 ①静态检查使程序更正确更有效 ②动态检查使编程方便, 但影响了可读性, 且 降低了执行效率

3. 强类型语言 若一个语言允许所有的类型静态检查 所有 4. Pascal是非强类型语言 ①编译时, 不能确定一个过程中的过程参 数和子程序参数类型 procedure who_knows(i, j: integer; procedure 3. 强类型语言 若一个语言允许所有的类型静态检查 所有 4. Pascal是非强类型语言 ①编译时, 不能确定一个过程中的过程参 数和子程序参数类型 procedure who_knows(i, j: integer; procedure f); var k: boolean; begin k: =j

②Pascal的子界不能静态检查 如: a: =b+c; 且a、b、c均属于子界类型1. . 10 ③变体记录的标识符可以在运行时改变 ④Pascal没有严格规定类型的一致性规则 ②Pascal的子界不能静态检查 如: a: =b+c; 且a、b、c均属于子界类型1. . 10 ③变体记录的标识符可以在运行时改变 ④Pascal没有严格规定类型的一致性规则

第九节 类型转换 1. 语言应该提供类型转换机制 如 A+B 2. 两种转换方式 ①拓展: 整型→实型 ②收缩: 实型→整型 有的“截断”, 有的“四舍五入” 第九节 类型转换 1. 语言应该提供类型转换机制 如 A+B 2. 两种转换方式 ①拓展: 整型→实型 ②收缩: 实型→整型 有的“截断”, 有的“四舍五入”

3. 注意语言规定的转换规则 ①Fortran: 低级类型→高级类型 ②Pascal允许: 整数→实数; 实数→整数 显式 转换(frunc、round) ③ALGOL 68提供了六种强制转换规则(隐 式的) ④Ada要求必须显式转换 例如: 3. 注意语言规定的转换规则 ①Fortran: 低级类型→高级类型 ②Pascal允许: 整数→实数; 实数→整数 显式 转换(frunc、round) ③ALGOL 68提供了六种强制转换规则(隐 式的) ④Ada要求必须显式转换 例如: 派生类型到母体类型的转换 P是POSITIVE的变量、L是LENGTH的变量 P: =POSITIVE(2*L+35);

第十节 类型等价 u T 1和T 2是相容的:T 1可赋给T 2,T 1可对应T 2 的形参;反之亦然。 1. 名字等价 两个变量的类型名相同。 第十节 类型等价 u T 1和T 2是相容的:T 1可赋给T 2,T 1可对应T 2 的形参;反之亦然。 1. 名字等价 两个变量的类型名相同。 2. 结构等价 两个变量的类型具有相同的结构。 验证法:用用户定义类型的定义来代替用户定 验证法 义名,重复这一过程,直到没有用户 定义类型名为止。

3. 两种相容性实现时的比较 ①名字等价的实现比较简单 ②结构等价的实现需要的模式匹配过程可能十 分复杂 3. 两种相容性实现时的比较 ①名字等价的实现比较简单 ②结构等价的实现需要的模式匹配过程可能十 分复杂

第十一节 实现模型 描述符: 描述数据对象的所有属性 数据 数据对象(存储区及其值) 第十一节 实现模型 描述符: 描述数据对象的所有属性 数据 数据对象(存储区及其值)

一. 内部类型和用户定义的非结构类型 1. 描述符一般由“类型”和一个指针组成 2. 子界的描述符必须包括子界的界值 3. 布尔型和字符型可以压缩存储 如: 整型 integer 一. 内部类型和用户定义的非结构类型 1. 描述符一般由“类型”和一个指针组成 2. 子界的描述符必须包括子界的界值 3. 布尔型和字符型可以压缩存储 如: 整型 integer

二. 结构类型 1. 笛卡尔积 ①各成分顺序排列 ②描述符包含: 类型名、构造符、若干 三元式。每个域对应一个三元式(选 择符名, 域类型, 指针) ③每个成分占整数个可编址的存储单 元(字编址或字节编址) ④可以用packed显式说明压缩存储 二. 结构类型 1. 笛卡尔积 ①各成分顺序排列 ②描述符包含: 类型名、构造符、若干 三元式。每个域对应一个三元式(选 择符名, 域类型, 指针) ③每个成分占整数个可编址的存储单 元(字编址或字节编址) ④可以用packed显式说明压缩存储

描述符 类型名 t 构造符 域 1 record 选择符 a 类型 real 引用 选择符 域 描述符 类型名 t 构造符 域 1 record 选择符 a 类型 real 引用 选择符 域 2 type t=record a:real; b:integer; end; 类型 引用 b integer 数据对象 浮点值 定点值

2. 有限映象 ①为每一成分分配整数个可编址的存储单 元 ②描述符包括: 类型名、构造符、定义域的 基类型、下界、上界、成分类型、单元个数、 首地址 ③地址公式的计算 b+k(i-m)=b-km+ki 其中b 为首地址,k为所占单元数,m为下界 ④内情向量 2. 有限映象 ①为每一成分分配整数个可编址的存储单 元 ②描述符包括: 类型名、构造符、定义域的 基类型、下界、上界、成分类型、单元个数、 首地址 ③地址公式的计算 b+k(i-m)=b-km+ki 其中b 为首地址,k为所占单元数,m为下界 ④内情向量

type a=array[1. . 10] of real; 描述符 类型名 构造符 基类型 下标类型 a array integer type a=array[1. . 10] of real; 描述符 类型名 构造符 基类型 下标类型 a array integer 下界 real 单元个数 浮点值 10 成分类型 浮点值 1 上界 数据对象 1 引用 浮点值

3. 序列 可变长串的表示: 静态描述符+动态描述符+堆 string 5 A L P H A nil 3. 序列 可变长串的表示: 静态描述符+动态描述符+堆 string 5 A L P H A nil

4. 判定或 ①判定或类型的变量分配的空间应足以容 纳需要最大空间的变体的值 ②Pascal的变体记录的表示包括: 描述符、数 据对象、case表、若干变体描述符 type v=record a: integer; case b: boolean 4. 判定或 ①判定或类型的变量分配的空间应足以容 纳需要最大空间的变体的值 ②Pascal的变体记录的表示包括: 描述符、数 据对象、case表、若干变体描述符 type v=record a: integer; case b: boolean of true: (c: integer); false: (d: integer; e: real) end;

描述符 v 数据对象 定点值 布尔值 variant record a integer • b boolean • • 描述符 v 数据对象 定点值 布尔值 variant record a integer • b boolean • • (false) d integer • e real • case表 true • • false (true) c integer • 变体描述符

5. 幂集 ①集合关联一个机器字, 通过每一位的 取值可知该集合中有基类型的哪些 元素 ②位操作 5. 幂集 ①集合关联一个机器字, 通过每一位的 取值可知该集合中有基类型的哪些 元素 ②位操作

6. 指针 指针变量的表示类似于内部类型,只是 其值为一地址,并且它指向的数据对象 分配在堆上 6. 指针 指针变量的表示类似于内部类型,只是 其值为一地址,并且它指向的数据对象 分配在堆上

7. 层次结构数据结构对象的表示 描述符中的类型可以指向另外的描述符 type t 1=array[0. . 3] of integer; t=record a: real; b: 7. 层次结构数据结构对象的表示 描述符中的类型可以指向另外的描述符 type t 1=array[0. . 3] of integer; t=record a: real; b: t 1; c: integer end; t 4=array[0. . 5] of integer; t 2=array[0. . 2] of t 4;

t record a real 浮点值 定点值 定点值 定点值 b c integer t 1 array t record a real 浮点值 定点值 定点值 定点值 b c integer t 1 array integer 0 3 integer 1

t 2 array integer 0 2 6 t 4 array integer 0 5 integer t 2 array integer 0 2 6 t 4 array integer 0 5 integer 1 定点值

第二章习题 所有习题均为思考题 第二章习题 所有习题均为思考题