编译原理与技术 类型检查 2018/11/21 《编译原理与技术》-类型检查.

Slides:



Advertisements
Similar presentations
JAVA 编 程 技 术 主编 贾振华 2010年1月.
Advertisements

天水圍的體育設施.
项目6 通用堆栈.
基本概論 Basic concepts.
电子成绩单项目实现.
编译原理第二次习题课 王静.
教 师:曾晓东 电 话: E_mail: 计算机软件技术基础 教 师:曾晓东 电 话: E_mail:
第一章 C语言概述 计算机公共教学部.
第三章 鏈結串列 Linked List.
Chapter 3.0 C語言的結構與指標 資料結構導論 - C語言實作.
第九章 系 统 安 全 性 9.1 结构体 9.2 结构体型数组  9.3 结构体型指针 9.4 内存的动态分配 9.5 共用体
2.1 基本資料型別 2.2 變數 2.3 運算式與運算子 2.4 輸出與輸入資料 2.5 資料型別轉換 2.6 實例
第一章 C语言概述.
程式設計 博碩文化出版發行.
C 程式設計— 結構 台大資訊工程學系 資訊系統訓練班.
陳維魁 博士 儒林圖書公司 第七章 參數的傳遞 陳維魁 博士 儒林圖書公司.
补充内容 结构体 概述 定义结构体类型和定义结构体变量 结构体变量的引用 结构体变量的初始化 指针与结构体 用typedef定义类型的别名.
第3章 變數、資料型別與運算子.
第3章 C 語言的基本知識.
结构体和共用体 2 梁春燕 华电信息管理教研室.
C++语言程序设计 C++语言程序设计 第六章 指针和引用 第十一组 C++语言程序设计.
Chap 9 结构 9.1 构建手机通讯录 9.2 结构变量 9.3 结构数组 9.4 结构指针.
第六章 运行时存储空间的组织和管理 术语 本章内容 讨论一个活动记录中的数据布局 程序执行过程中,所有活动记录的组织方式 过程的活动
第9章 自訂資料型態 – 結構 9-1 結構資料型態 9-2 結構陣列 9-3 指標與結構 9-4 動態記憶體配置 9-5 聯合資料型態
STRUCTURE 授課:ANT 日期:2010/5/12.
C++语言程序设计 C++语言程序设计 第四章 数组及自定义数据类型 C++语言程序设计.
授课老师:龚涛 信息科学与技术学院 2018年3月 教材: 《Visual C++程序员成长攻略》 《C++ Builder程序员成长攻略》
Object-Oriented Programming in C++ 第一章 C++的初步知识
第三章 C++中的C 面向对象程序设计(C++).
C语言程序设计 李祥.
C 程式設計— 結構 台大資訊工程學系 資訊系統訓練班.
第五章 指针 5.1 指针的概念和定义 5.2 指针运算 5.3 指针和数组 5.4 字符串指针 5.5 指针数组 5.6 指向指针的指针
第3章 變數、資料型別與運算子 3-1 變數與資料型別的基礎 3-2 變數的命名與宣告 3-3 資料型別 3-4 運算式與運算子
變數命名 保留字(Reserved Word)
第13章 结构体的应用 13.1 了解由用户构造的数据类型 13.2 结构体类型说明及结构体变量 13.3 结构体数组
明解C++教學手冊 柴田望洋 博士 著 書號:PG20269
中间代码生成.
C++语言程序设计 C++语言程序设计 第七章 类与对象 第十一组 C++语言程序设计.
Struct結構 迴圈
C语言程序设计.
第十章 用户自定义数据类型 目录 学生信息管理系统的开发 结构体数据类型的概述 结构体变量的使用 结构体数组
OOP6 結構Struct 黃兆武.
第十章 结构体与链表 西安工程大学.
第二章 Java基本语法 讲师:复凡.
Java變數 2014/6/24.
第2章 数据类型及表达式 本章导读 本章主要知识点 《 C语言程序设计》 (Visual C++ 6.0环境)
陳維魁 博士 儒林圖書公司 第三章 變數與繫結 陳維魁 博士 儒林圖書公司.
第二章 Java基本语法 讲师:复凡.
习题课
习题课 编译原理与技术 计算机科学与技术学院 李诚.
<编程达人入门课程> 本节内容 为什么要使用变量? 视频提供:昆山爱达人信息技术有限公司 官网地址: 联系QQ:
第二章 Java语法基础.
第二章 类型、对象、运算符和表达式.
第二章 基本数据类型 ——数据的表示.
Review 1~3.
Java软件设计基础 课后作业.
#include <iostream.h>
第二章 Java基本语法 讲师:复凡.
本节内容 指针类型.
第二章 Java基本语法 讲师:复凡.
第十二章 位运算.
1.4WIN32中的宽字符.
本章主題 C++的程式結構 資料型態與宣告 算術運算 簡易的輸入輸出指令 程式編譯(Compile)的過程與原理.
變數、資料型態、運算子.
第2章 Java语言基础.
C/C++基礎程式設計班 C語言入門、變數、基本處理與輸入輸出 講師:林業峻 CSIE, NTU 3/7, 2015.
第9章 C++程序设计初步 9.1 C++的特点 9.2 最简单的C++程序 9.3 C++的输入输出 9.4 函数的重载
本节内容 指针类型 视频提供:昆山爱达人信息技术有限公司 官网地址: 联系QQ: QQ交流群 : 联系电话:
安排座位.
Presentation transcript:

编译原理与技术 类型检查 2018/11/21 《编译原理与技术》-类型检查

类型检查 类型体制 类型检查 - 类型等价 类型转换 - 隐式转换 - 显式转换 类型推导 - 算符重载 2018/11/21 《编译原理与技术》-类型检查

类型体制 程序设计语言中的类型 - 类型代表着某类值(域)的集合,如整型(数)、实型(数)、字符串等。 - 类型本身具有结构;多数语言提供称为基本类型或预定义类型的“内建”类型,如C的int,char和double。同时可以应用类型构造器作用于基本类型得到“复合类型”,常见的类型构造器有record/struct、array、set、pointer、function等。 - 用“类型表达式”来表示具有类型的语言结构 -“类型体制”也就是将类型表达式指派到语言结构上的规则(集合),而类型检查则是来实现这个类型体制。 2018/11/21 《编译原理与技术》-类型检查

类型窄化(Narrowing)必须做type-cast 基本类型 C Java long double double double float float long long long int long short int char short byte char boolean 类型加宽(Widening) unsigned 类型窄化(Narrowing)必须做type-cast 2018/11/21 《编译原理与技术》-类型检查

- 联合/变体(union/variant) - 位域(bit fields) 复合类型 - 结构/记录(不同类型的对象聚集) C Pascal struct foo { RECORD int a; var a : integer; float b; var b : real; } ; END ; struct foo X; X.a = … - 联合/变体(union/variant) - 位域(bit fields) 2018/11/21 《编译原理与技术》-类型检查

a[0] = … a = new int[11]; a[0] := … 复合类型 - 数组(相同类型的对象聚集) C Java Pascal int a[11]; int [ ] a; var a : array [0..10] of integer; a[0] = … a = new int[11]; a[0] := … 2018/11/21 《编译原理与技术》-类型检查

int *a; Integer Ref; var p : ^ integer; int x = 11; new(p); 复合类型 - 指针 C Java Pascal int *a; Integer Ref; var p : ^ integer; int x = 11; new(p); Ref = new Integer(15); a = &x; Ref . intValue() ; *a = … p := … p^ := … 2018/11/21 《编译原理与技术》-类型检查

如: int foo(…)  (void) foo(…) - 通用指针 如C中,int *ptr ; …  (void *) ptr - 返回类型、空参数列表 如C中:void foo( void ) - cast 如: int foo(…)  (void) foo(…) - 通用指针 如C中,int *ptr ; …  (void *) ptr 2018/11/21 《编译原理与技术》-类型检查

- 采用类型构造器作用于类型表达式上,可以得到新的类型表达式。 语言结构的类型可表示为类型表达式。 - 基本类型可作为类型表达式; - 类型名也可以是类型表达式; - 采用类型构造器作用于类型表达式上,可以得到新的类型表达式。 (1)数组:array( I, T ) ; I 、T分别为下标与数组元素的类型; (2)积:x ; 如 T1 x T2 ; (3)记录:record ( (域名x域类型) 的积 ) (4)指针: pointer( T ) ; T 为所指对象类型 (5)函数:参数类型的积  结果类型 - 类型表达式可以含(类型)变量。 2018/11/21 《编译原理与技术》-类型检查

student stu1, stu2; //stu1的类型表达式如下: e.g. 给出以下声明的类型表达式: typedef struct { char name[32]; int age; float score; } student; student stu1, stu2; //stu1的类型表达式如下: record( (name x array(0..31, char) ) x (age x int ) x (score x float ) ) 2018/11/21 《编译原理与技术》-类型检查

student * enter( char * name, e.g. 给出以下函数的类型表达式: student * enter( char * name, int age, float score ) 函数enter的类型表达式为: ( pointer(char) x int x float )  pointer( student) 2018/11/21 《编译原理与技术》-类型检查

类型检查 类型检查就是语言类型体制的“实现” 如: 运算符mod(或C中的%)一般要求参与运算的左、右表达式类型均为整型(或兼容类型),那么可以将此类型检查“形式化”为: EE1 mod E2 { if (E1.type == INT) and (E2.type == INT) then E.type :=INT else E.type := type_error } 2018/11/21 《编译原理与技术》-类型检查

EE1 [ E2 ] { if (E1.type == array(s,t) ) and (E2.type == s) 而数组元素的类型检查可描述如下: EE1 [ E2 ] { if (E1.type == array(s,t) ) and (E2.type == s) then E.type := t else E.type := type_error } 2018/11/21 《编译原理与技术》-类型检查

- 确定两个名字或值是否具有“相同”的类型 结构等价:structure equivalence 类型等价 - 确定两个名字或值是否具有“相同”的类型 结构等价:structure equivalence 两个类型结构等价,如果它们的组成成分相同且组织方式相同;是一种面向实现“较低级”的“类型检查”; 存在问题:不能区分那些虽然内部结构完全相同,但其实确为不同的类型。如C的2个结构定义: struct person { struct school { char * name; char * name; char * address; char * address; int age; int age; } a; } b; a = b; //??? C中除了结构类型外(struct),其他类型均采用结构等价。 2018/11/21 《编译原理与技术》-类型检查

int y; /* x 和 y 是否类型(名)等价? */ 名等价:name equivalence -每一个类型定义可视为引入新的类型; - 类型别名,如C中: typedef int INT; INT x; int y; /* x 和 y 是否类型(名)等价? */ - 严格(strict)名等价:将类型的别名也看成不同的类型;即,将别名看成一个新的类型“定义”; - 松散(loose)名等价:类型的别名看成相同的类型;即,将别名看成一个“声明”,而与原来的类型共享有关“定义”。 C中结构类型采用名等价。 2018/11/21 《编译原理与技术》-类型检查

TYPE Alink = POINTER TO Cell; TYPE Blink = Alink; e.g. 指出以下变量声明中的类型等价关系 TYPE Cell = … TYPE Alink = POINTER TO Cell; TYPE Blink = Alink; VAR p,q : POINTER TO Cell; VAR r : Alink; VAR s : Blink; VAR t,u : POINTER TO Cell; VAR v : Alink; 2018/11/21 《编译原理与技术》-类型检查

严格名等价: p和q具有相同类型; t和u具有相同类型; r和v具有相同类型; 松散名等价: r、v和u具有相同类型; 结构等价: 所有7个变量具有相同类型! p(或q)与t(或u)是否名等价呢? 一般情况下,p或t的类型,即“无名”类型: POINTER TO Cell 被看成不同的类型定义! 2018/11/21 《编译原理与技术》-类型检查

类型转换 在某些程序上下文环境中,所使用的对象的类型为A,而实际所需的类型确为B。此时需要对有关“类型”进行转换。例如: (1) int i ; float f ; f = i; //赋值语句 (2) 100 + 200.8 //表达式 (3) char * p ; p = (char*) malloc(…); // 函数返回值(参数) 隐式转换- 类型强制(type coercion) 显式转换-type cast 2018/11/21 《编译原理与技术》-类型检查

- 类型兼容性(type compatibility) 隐式转换(类型强制) - 类型兼容性(type compatibility) 在实际需要类型B的上下文中,也允许使用类型A;此时,多由编译器完成相关类型检查和(产生代码)进行相关类型的转换。 C/C++中有许多类型隐式转换,如: short = unsigned long //取低端2字节 unsigned long = short //符号扩展 short = char // 0 或符号扩展 float = unsigned long // 无符号长整数->浮点数,可能丢失精度 double = float; // 单精度浮点数->双精度浮点数 float = double // 双精度浮点数->单精度浮点数,可能丢失精度 2018/11/21 《编译原理与技术》-类型检查

long double + any  long double 否则 double + any  double 否则 隐式转换 更多算术运算中的转换:如果 long double + any  long double 否则 double + any  double 否则 float + any  float 否则 unsigned long + any  unsigned long 否则 long + unsigned int  unsigned long 否则 long + any  long 否则 unsigned int + any  unsigned int 否则 int( any ) + any  int 2018/11/21 《编译原理与技术》-类型检查

显式转换 - 可以看成是“函数”调用 如下C的声明: struct person { struct school { char * name; char * name; char * address; char * address; int age; int age; } a; } b; 虽然a 和 b 结构上“是”等价的,但C语言要求对结构进行名等价,因此语句 a = ( person ) b ; 不能实行转换! 考虑语句 a = * ( person *) &b; // OK? ! 2018/11/21 《编译原理与技术》-类型检查

类型推导 语言结构的类型(含义)可能随上下文而变化。如表达式 a + b ,当a和b均为整型时,表达式亦为整型,而a或b为complex(复数型),则为complex型。 算符或函数重载(overloading) - 算符或函数在不同的上下文中有不同的含义 - 多数时候可以根据上下文消除重载; 2018/11/21 《编译原理与技术》-类型检查

重载 多数语言中对算符“×”重载,如: int × int  int int × int  complex complex × complex  complex 设 3,4 ,5仅为整型;z为complex型,那么 3 ×(4 × 5) 和 ( 3 × 5 ) × z 的类型是什么? 2018/11/21 《编译原理与技术》-类型检查