习题课 2017-11-23.

Slides:



Advertisements
Similar presentations
“ 我们的 12 班 我们的家 ” ——2014 级 12 班 班级文化建设缩影. “ 做好人,读好书。 ” (理念上) “ 惜时好学,动静分明。 ” (态度上)
Advertisements

拉动内需,改善经济 工商 1 班 陆丹丹 16 陆晨莉 19. 国务院出台内需十措施 确定 4 万亿投资 一 加快建设保障性安居工程 二 加快农村基础设施建设 三 加快铁路、公路和机场等重大基础设施建设 四 加快医疗卫生、文化教育事业发展 五 加强生态环境建设 六 加快自主创新和结构调整 七 加快地震灾区灾后重建各项工作.
C语言程序设计 主讲教师 :张群燕 电话:
班級:醫管3B 組別:第二組 組員:王品媛、郭雅瑄、謝淑玲、蔡孟蔙
电子成绩单项目实现.
编译原理第二次习题课 王静.
“八皇后”问题 崔萌萌 吕金华.
Memory Pool ACM Yanqing Peng.
第一章 C语言概述 计算机公共教学部.
周 瑜 與 諸 葛 亮 的 才 智 對 口 編輯:Francis Lin 請點滑鼠換頁.
响沙之王——银肯响沙 响沙之王——银肯响沙.
计算机硕士专业基础—C语言 赵海英
函数式编程语言、编程和程序验证 计算机科学与技术学院 陈意云
5.
補充: Input from a text file
認識拿破崙˙波拿巴 關於一位運氣很差的矮子的趣事兩三件 我不是矮子!! 本日主角 重點不是這個吧? 惡搞人員:橘蘋3顆和一隻小精靈.
第4章 数组 数组是由一定数目的同类元素顺序排列而成的结构类型数据 一个数组在内存占有一片连续的存储区域 数组名是存储空间的首地址
内蒙古景观与区划 人文景观 人文景观是指有人为因素作用形成(构成)的景观。人为因素主要有文化、建筑等因素。
新世代計算機概論 第14章 程式語言.
Using C++ The Weird Way Something about c++11 & OOP tricks
第4章 鏈結串列(Linked Lists) 4-1 動態記憶體配置-(6) 4-2 鏈結串列的基礎-(7)
Linked List Operations
單向鏈結串列 Singly Linked Lists.
第6章 佇列(Queues) 6-1 佇列的基礎 6-2 佇列的表示法 6-3 環狀佇列 6-4 雙佇列.
第一章 C语言概述.
C的發展史 C程式初體驗 C程式設計基本注意事項 上機實習課程
计算概论 第二十一讲 文件操作 北京大学信息学院.
Derived Class 前言 衍生類別的定義 單一繼承 public, protected, 和 privated 基底類別
编译原理与技术 类型检查 2018/11/21 《编译原理与技术》-类型检查.
Scope & Lifetime 前言 Local Scope Global Functions & Objects
第12章 樹狀搜尋結構 (Search Trees)
授课老师:龚涛 信息科学与技术学院 2018年3月 教材: 《Visual C++程序员成长攻略》 《C++ Builder程序员成长攻略》
港口股份有限公司东源分公司 降本增效 部门:机械队流机二班 发言人:程广州.
Function.
程序设计期末复习 黎金宁
第 6 章 函式.
第2章 线性表 线性表抽象数据类型 顺序表 主要知识点 单链表 循环单链表 循环双向链表 静态链表 设计举例.
第5章 堆疊(Stacks) 5-1 堆疊的基礎 5-2 堆疊的表示法 5-3 堆疊的應用 - 運算式的計算與轉換
第5章 堆疊(Stacks) 5-1 堆疊的基礎 5-2 堆疊的表示法 5-3 堆疊的應用 - 運算式的計算與轉換
6 使用者函數 6.1 函數定義 宣告函數 呼叫函數 呼叫多個函數 6-6
新觀念的 VB6 教本 第 6 章 資料型別.
明解C++教學手冊 柴田望洋 博士 著 書號:PG20269
中间代码生成.
計數式重複敘述 for 迴圈 P
第1章 概述 本章要点: C语言程序结构和特点 C语言程序的基本符号与关键字 C语言程序的编辑及运行 学习方法建议:
第2章 MATLAB程序设计 编者.
第五章 递归与广义表 递归的概念 递归过程与递归工作栈 递归与回溯 广义表.
C#程序设计基础 $3 成员、变量和常量.
第六章 语法制导的翻译 本章内容 介绍一种语义描述方法:语法制导的翻译,介绍语法制导的翻译的实现方法。
北投溫泉博物館 建築特色 ★小組成員:高103林孟璇、林念儀、施妤柔★.
函式庫補充資料.
指標
7.1 C程序的结构 7.2 作用域和作用域规则 7.3 存储属性和生存期 7.4 变量的初始化
习题课 编译原理与技术 计算机科学与技术学院 李诚.
C qsort.
<编程达人入门课程> 本节内容 为什么要使用变量? 视频提供:昆山爱达人信息技术有限公司 官网地址: 联系QQ:
第7章 程序的结构 四、生存期与存储属性 五、extern关键字与外部连接属性 六、static关键字与内部连接属性.
第二章 类型、对象、运算符和表达式.
本节内容 Lua基本语法.
授课老师:龚涛 信息科学与技术学院 2016年3月 教材:《Visual C++程序员成长攻略》 《C++ Builder程序员成长攻略》
#include <iostream.h>
第4章 鏈結串列(Linked Lists) 4-1 動態記憶體配置-(6) 4-2 鏈結串列的基礎-(7)
Go 语言编程 —— 平台研发部 吴植民.
本章主題 C++的程式結構 資料型態與宣告 算術運算 簡易的輸入輸出指令 程式編譯(Compile)的過程與原理.
第三章 高级函数特性.
第六章 复合数据类型 指针的声明与使用 数组的声明与使用 指针与数组的相互引用 字符串及相关库函数 new与delete
Introduction to the C Programming Language
函式庫補充資料 1.
隨機函數.
Presentation transcript:

习题课 2017-11-23

H7 4.12(b) 文法如下: S→ 𝐿 | 𝑎 L →𝐿,𝑆 | 𝑆 (1)写一个翻译方案,它打印出每个a在句子中是第几个字符。例如,当 句子是(a,(a,(a,a),(a)))时,打印的结果是2, 5, 8, 10, 14。 (2)写出相应的语法制导定义 (3)写出相应的预测翻译器 (4)写出自下而上分析的栈操作代码

概念区分 语义规则和产生式相联系的两种方式 语法制导定义 将文法符号和某些属性相关联,并通过语义规则来描述如何计算属性 的值,没有描述这些规则的计算时机 语法制导的翻译方案 在产生式的右部的适当位置,插入相应的语义动作,按照分析的进程, 执行遇到的语义动作,从而明确了语法分析过程中属性的计算时机。

H7 a自身的信息无法确定a在序列中的位置,因此必须要借助继承属性。 方法一: 继承属性 in:该文法符号推出的字符序列的前面已经有多少字符 4.12(b) 文法如下: S→ 𝐿 | 𝑎 L →𝐿,𝑆 | 𝑆 (1)写一个翻译方案,它打印出每个a 在句子中是第几个字符。例如,当句 子是(a,(a,(a,a),(a)))时,打印的结果是2, 5, 8, 10, 14。 H7 a自身的信息无法确定a在序列中的位置,因此必须要借助继承属性。 方法一: 继承属性 in:该文法符号推出的字符序列的前面已经有多少字符 综合属性 out:该文法符号推出的字符序列的最后一个字符在序列中是第几 个字符 S’ → { S.in = 0; } S S → { L.in = S.in +1; } (L) { S.out = L.out + 1; } S → a { S.out = S.in + 1; print (S.out); } L → { L1.in = L.in; } L1, { S.in = L1.out + 1; } S {L.out = S.out; } L → { S.in = L.in; } S { L.out = S.out; }

H7 a自身的信息无法确定a在序列中的位置,因此必须要借助继承属性。 方法二: 继承属性 in:该文法符号推出的字符序列的前面已经有多少字符 4.12(b) 文法如下: S→ 𝐿 | 𝑎 L →𝐿,𝑆 | 𝑆 (1)写一个翻译方案,它打印出每个a 在句子中是第几个字符。例如,当句 子是(a,(a,(a,a),(a)))时,打印的结果是2, 5, 8, 10, 14。 H7 a自身的信息无法确定a在序列中的位置,因此必须要借助继承属性。 方法二: 继承属性 in:该文法符号推出的字符序列的前面已经有多少字符 综合属性 total:该文法符号推出的字符序列所包含的字符总数 S’ → { S.in = 0; } S S → { L.in = S.in +1; } (L) { S.total = L.total + 2; } S → a { S.total = 1; print (S.in + 1); } L → { L1.in = L.in; } L1, { S.in = L1.in + L1.total + 1; } S {L.total = L1.total +S.total + 1; } L → { S.in = L.in; } S { L.total = S.total; }

H7 a自身的信息无法确定a在序列中的位置,因此必须要借助继承属性。 方法一的语法制导定义: 4.12(b) 文法如下: S→ 𝐿 | 𝑎 L →𝐿,𝑆 | 𝑆 写出相应的语法制导定义 H7 a自身的信息无法确定a在序列中的位置,因此必须要借助继承属性。 方法一的语法制导定义: 继承属性 in:该文法符号推出的字符序列的前面已经有多少字符 综合属性 out:该文法符号推出的字符序列的最后一个字符在序列中是第几 个字符 产生式 语义规则 S’ → S S.in = 0; S → (L) L.in = S.in +1; S.out = L.out + 1; S → a S.out = S.in + 1; print (S.out); L → L1, S L1.in = L.in; S.in = L1.out + 1; L.out = S.out; L → S S.in = L.in; L.out = S.out;

H7 消除左递归 S’ → S S → (L) S → a L → ST T → ,ST | 𝜀 产生式 语义规则 S’ → S 4.12(b) 文法如下: S→ 𝐿 | 𝑎 L →𝐿,𝑆 | 𝑆 写出相应的预测翻译器 H7 消除左递归 S’ → S S → (L) S → a L → ST T → ,ST | 𝜀 产生式 语义规则 S’ → S S.in = 0; S → (L) L.in = S.in +1; S.out = L.out + 1; S → a S.out = S.in + 1; print (S.out); L → ST S.in = L.in; T.in = S.out; L.out = T.out; T → ,ST1 S.in = T.in + 1; T1.in = S.out; T.out = T1.out T → 𝜀 T.in = T.out 构造预测分析器时要消除左递归

H7 int S’(){ return S(0); } int S(int b){ int in, out; 产生式 语义规则 S’ → S S.in = 0; S → (L) L.in = S.in +1; S.out = L.out + 1; S → a S.out = S.in + 1; print (S.out); L → ST S.in = L.in; T.in = S.out; L.out = T.out; T → ,ST1 S.in = T.in + 1; T1.in = S.out; T.out = T1.out T → 𝜀 T.in = T.out H7 int S(int b){ int in, out; if(lookahead == ‘(’){ in = b + 1; match(‘(’); out = L(in) + 1; match(‘)’) }else { match(‘a’); out = b + 1; print(out); } return out; int S’(){ return S(0); }

H7 int L(int b){ int out; out = S(b); out = T(out); return out; } 产生式 语义规则 S’ → S S.in = 0; S → (L) L.in = S.in +1; S.out = L.out + 1; S → a S.out = S.in + 1; print (S.out); L → ST S.in = L.in; T.in = S.out; L.out = T.out; T → ,ST1 S.in = T.in + 1; T1.in = S.out; T.out = T1.out T → 𝜀 T.in = T.out H7 int T(int b) { int out; if(lookahead == ‘,’){ match(‘,’); out = S(b+1); out = T(out); }else{ out = b; } return out; int L(int b){ int out; out = S(b); out = T(out); return out; }

H7 引入标记非终极符M,N,R,P 产生式 语义规则 栈操作代码 S’ → MS S.in = M.out 4.12(b) 文法如下: S’ → S S → (L) S → a L → ST T → ,ST | 𝜀 写出自下而上分析的栈操作代码 H7 引入标记非终极符M,N,R,P 产生式 语义规则 栈操作代码 S’ → MS S.in = M.out Stack[top - 1] = Stack[top] M → 𝜀 M.out = 0 Stack[top + 1] = 0 S → (NL) N.in = S.in + 1, L.in = N.out; S.out = L.out + 1; Stack[top - 3] = Stack[top - 1] + 1 N → 𝜀 N.out = N.in Stack[top + 1] = Stack[top - 1] + 1 S → a S.out = S.in + 1; print (S.out); Stack[top] = Stack[top - 1] + 1 L → SRT S.in = L.in; R.in = S.in; T.in = R.out, L.out = T.out; Stack[top - 2] = Stack[top] R → 𝜀 R.out = R.in Stack[top + 1] = Stack[top - 1] T → ,SPT1 S.in = T.in + 1; P.in = S.in; T1.in = P.out; T1.out = S.out; Stack[top - 3] = Stack[top] P → 𝜀 P.out = P.in Stack[top + 1] = Stack[top] T → 𝜀 T.out = T.in Stack[top] = Stack[top - 1]

H8 5.5 假如有下列C的声明: typedef struct{ int a, b; } CELL, *PCELL; CELL foo[100]; PCELL bar(x, y) int x; CELL y; {} 为变量foo和函数bar的类型写出类型表达式。

H8 CELL foo[100]; array(Range ?, TypeOfElement ?) typedef struct{ int a, b; } CELL, *PCELL; CELL foo[100]; PCELL bar(x, y) int x; CELL y; {} 为变量foo和函数bar的类型写出类型表达式。 CELL foo[100]; array(Range ?, TypeOfElement ?) array(0..99, TypeOfElement ?) array(0..99, CELL) array(0..99, record((int a) ×(int b))) array(0..99, record((a × integer) ×(b × integer)))

H8 PCELL bar(x, y) int x; CELL y; {} typedef struct{ int a, b; } CELL, *PCELL; CELL foo[100]; PCELL bar(x, y) int x; CELL y; {} 为变量foo和函数bar的类型写出类型表达式。 PCELL bar(x, y) int x; CELL y; {} TypeOfParameters? -> TypeOfReturnValue? (int ×CELL) -> PCELL (integer ×record((a × integer) ×(b × integer))) -> PCELL (integer ×record((a × integer) ×(b × integer))) -> pointer(record((a × integer) ×(b × integer)))

H8 5.12 拓展5.3.3节的类型检查,使之能包含记录。有关记录部分的 类型和记录域引用表达式的语法如下: T→ 𝒓𝒆𝒄𝒐𝒓𝒅 𝑓𝑖𝑒𝑙𝑑𝑠 𝐞𝐧𝐝 𝑓𝑖𝑒𝑙𝑑𝑠→ 𝑓𝑖𝑒𝑙𝑑𝑠;𝑓𝑖𝑒𝑙𝑑 | 𝑓𝑖𝑒𝑙𝑑 𝑓𝑖𝑒𝑙𝑑→𝐢𝐝 :𝑇 𝐸→𝐸.𝐢𝐝

H8 5.12 拓展5.3.3节的类型检查,使之能包含记录。有关记录部分的 类型和记录域引用表达式的语法如下: T→ 𝒓𝒆𝒄𝒐𝒓𝒅 𝑓𝑖𝑒𝑙𝑑𝑠 𝐞𝐧𝐝 {T.type = record(fields.type)} 𝑓𝑖𝑒𝑙𝑑𝑠→ 𝑓𝑖𝑒𝑙𝑑𝑠;𝑓𝑖𝑒𝑙𝑑 {fields.type = fields.type × field.type} 𝑓𝑖𝑒𝑙𝑑𝑠→ 𝑓𝑖𝑒𝑙𝑑 {fields.type = field.type} 𝑓𝑖𝑒𝑙𝑑→𝐢𝐝 :𝑇 {field.type = id.name × T.type} 𝐸→ 𝐸 1 .𝐢𝐝 {E.type = if(E1.type == record(t)) lookup(E1.type, id.name) else type_error;}

H8 5.13在文件stdlib.h中,关于qsort的外 部声明如下: #include <stdlib.h>   typedef struct{ int Ave; double Prob; }HYPO; HYPO astHypo; int n; int HypoCompare(HYPO stHypo1, HYPO stHypo2) { if (stHypo1->Prob>stHypo2->Prob){ return(-1); }else if (stHypo1->Prob<stHypo2->Prob) { return(1); }else{ return(0); } }/ end of function HypoCompare / main() qsort ( astHypo,n,sizeof(HYPO),HypoCompare); H8 5.13在文件stdlib.h中,关于qsort的外 部声明如下: extern void qsort(void *, size_t, size_t, int (*)(const void *, const void *)); 用SPARC/Solaris C编译器编译下面的C 程序时,错误信息如下: type.c:24: warning: passing argument 4 of `qsort’ from incompatible pointer type 请你对该程序略作修改,使得该警告 错误能消失,并且不改变程序的结果。

H8 5.13在文件stdlib.h中,关于qsort的外 部声明如下: #include <stdlib.h>   typedef struct{ int Ave; double Prob; }HYPO; HYPO astHypo; int n; int HypoCompare(HYPO stHypo1, HYPO stHypo2) { if (stHypo1->Prob>stHypo2->Prob){ return(-1); }else if (stHypo1->Prob<stHypo2->Prob) { return(1); }else{ return(0); } }/ end of function HypoCompare / main() qsort ( astHypo, n, sizeof(HYPO), HypoCompare); H8 5.13在文件stdlib.h中,关于qsort的外 部声明如下: extern void qsort(void *, size_t, size_t, int (*)(const void *, const void *)); 问题:qsort的第四个形式参数类型与 函数调用的传参类型不一致

H8 5.13在文件stdlib.h中,关于qsort的外 部声明如下: #include <stdlib.h>   typedef struct{ int Ave; double Prob; }HYPO; HYPO astHypo; int n; int HypoCompare(const void stHypo1, const voidstHypo2) { if ((HYPO *)stHypo1->Prob>(HYPO *)stHypo2->Prob){ return(-1); }else if ((HYPO *)stHypo1->Prob<(HYPO *)stHypo2->Prob) { return(1); }else{ return(0); } }/ end of function HypoCompare / main() qsort ( astHypo, n, sizeof(HYPO), HypoCompare); H8 5.13在文件stdlib.h中,关于qsort的外 部声明如下: extern void qsort(void *, size_t, size_t, int (*)(const void *, const void *)); 问题:qsort的第四个形式参数类型与 函数调用的传参类型不一致 方法一:修改HypoCompare函数形式参 数的类型

H8 5.13在文件stdlib.h中,关于qsort的外 部声明如下: #include <stdlib.h>   typedef struct{ int Ave; double Prob; }HYPO; HYPO astHypo; int n; int HypoCompare(HYPO stHypo1, HYPO stHypo2) { if (stHypo1->Prob>stHypo2->Prob){ return(-1); }else if (stHypo1->Prob<stHypo2->Prob) { return(1); }else{ return(0); } }/ end of function HypoCompare / main() qsort ( astHypo, n, sizeof(HYPO), int (*)(const void *, const void *) HypoCompare); H8 5.13在文件stdlib.h中,关于qsort的外 部声明如下: extern void qsort(void *, size_t, size_t, int (*)(const void *, const void *)); 问题:qsort的第四个形式参数类型与 函数调用的传参类型不一致 方法二:强制修改qsort函数调用中第 四个参数的类型

H9 5.16对下面的每对表达式, (a) 1 (2  1)  5.16对下面的每对表达式, (a) 1 (2  1) (b) array (1)  (pointer (1) 2) (c) 1  2 找出(a) 和 (b) 、(b)和(c)最一般的合一代换:

H9 (a)与(b) S(α1) = array ( β1 ) S(α2) = pointer ( β1 )  5.16对下面的每对表达式, (a) 1 (2  1) (b) array (1)  (pointer (1) 2) (c) 1  2 找出(a) 和 (b) 、(b)和(c)最一般的合一代换:  (a)与(b) S(α1) = array ( β1 ) S(α2) = pointer ( β1 ) S(β2) = array ( β1 ) 什么是最一般的合一代换

H9 (b)与(c) S(γ1) = array ( β1 ) S(γ2) = pointer ( β1 ) → β2  5.16对下面的每对表达式, (a) 1 (2  1) (b) array (1)  (pointer (1) 2) (c) 1  2 找出(a) 和 (b) 、(b)和(c)最一般的合一代换:  (b)与(c) S(γ1) = array ( β1 ) S(γ2) = pointer ( β1 ) → β2

H9  5.17效仿例5.5,推导下面map的多态类型: map : . . ( (   )  list ( ) )  list ( ) map的ML定义是 fun map ( f, l ) = if null (l ) then nil else cons (f (hd (l)), map (f, tl (l ) ) ); 在这个函数体中,内部定义的标识符的类型是: null : . list ( )  boolean ; nil : . list ( ) ; cons : . (  list ( ) )  list ( ) ; hd : . list ( )   ; tl : . list ( )  list ( ) ;

H9 第一步:列出类型声明和要检查的表达式 f : α l : β  5.17效仿例5.5,推导下面map的多态类型: map : . . ( (   )  list ( ) )  list ( ) map的ML定义是 fun map ( f, l ) = if null (l ) then nil else cons (f (hd (l)), map (f, tl (l ) ) ); 在这个函数体中,内部定义的标识符的类型是: null : . list ( )  boolean ; nil : . list ( ) ; cons : . (  list ( ) )  list ( ) ; hd : . list ( )   ; tl : . list ( )  list ( ) ; H9  第一步:列出类型声明和要检查的表达式 f : α l : β if: . boolean  list ( )  list ( )  list ( ) null : . list ( )  boolean ; nil : . list ( ) ; cons : . (  list ( ) )  list ( ) ; hd : . list ( )   ; tl : . list ( )  list ( ) ; match( map ( f, l ), if null (l ) then nil else cons (f (hd (l)), map (f, tl (l ) ) ); )

map : . . ( (   )  list ( ) )  list ( ) fun map ( f, l ) = if null (l ) then nil else cons (f (hd (l)), map (f, tl (l ) ) ); null : . list ( )  boolean ; nil : . list ( ) ; cons : . (  list ( ) )  list ( ) ; hd : . list ( )   ; tl : . list ( )  list ( ) ; H9  第二步:代换推导 行 定型断言 代换 规则 1 f : α (Exp Id) 2 l : β 3 map : γ 4 map ( f , l ) : δ γ = ( α  β ) → δ (Exp Funcall) 5 null : list (α0) → boolean (Exp Id Fresh) 6 null ( l ) : boolean β = list (α0) (Exp Funcall + (2)) 7 nil : list (α1) 8 l : list (α0) 由(2)可得 9 hd : list (α2) → α2 ML ('Meta Language') is a general-purpose functional programming language. 

H9 第二步:代换推导 至此有map : ( (α0→α1)  list(α0) )→list(α1) map : . . ( (   )  list ( ) )  list ( ) fun map ( f, l ) = if null (l ) then nil else cons (f (hd (l)), map (f, tl (l ) ) ); null : . list ( )  boolean ; nil : . list ( ) ; cons : . (  list ( ) )  list ( ) ; hd : . list ( )   ; tl : . list ( )  list ( ) ; H9 行 定型断言 代换 规则 9 hd : list (α2) → α2 (Exp Id Fresh) 10 hd ( l ) : α0 α2 = α0 (Exp Funcall) 11 f ( hd ( l ) ) : α3 α = α0→α3 ( Exp Id ) 12 f : α0→α3 由(1)可得 13 tl : list (α4)→ list (α4) 14 tl ( l ) : list (α0) α4 = α0 15 map : ((α0→α3) list(α0))→ δ 由(3)可得 16 map ( f , tl ( l ) ) : δ 17 cons : α5  list(α5) → list(α5) 18 cons (…) : list (α3) α5 = α3 , δ=list(α3) 19 if : boolean  list(α6)  list(α6) →list(α6) 20 if (…) : list (α1) α6 = α1 , α3 = α1 21 match : α7  α7 → α7 22 match (…) : list (α1) α7 = list (α1)  第二步:代换推导 ML ('Meta Language') is a general-purpose functional programming language.  至此有map : ( (α0→α1)  list(α0) )→list(α1) 所以map : ∀ α . ∀ β . ( ( α → β )  list ( α ) ) → list ( β )

H9 5.21 使用例5.9的规则,确定下列哪些表达式有唯一类型(假定z 是复数): (a) 123 (b) 1  (z 2) (c) (1  z )  z

H9 5.21 使用例5.9的规则,确定下列哪些表达式有唯一类型(假定z 是复数): (a) 123 (b) 1  (z 2) (c) (1  z )  z 运算规则: int  int -> int int  int -> complex complex  complex -> complex

H9 5.21 使用例5.9的规则,确定下列哪些 表达式有唯一类型(假定z是复数): (a) 123 (b) 1  (z 2) (c) (1  z )  z 运算规则: int  int -> int int  int -> complex complex  complex -> complex H9 1*2*3:{int, complex} 1*2:{int, complex} *: {i  i -> i, i  i -> c, c  c -> c} 3:{int, complex} 1:{int, complex} 2:{int, complex} 类型不唯一 *: {i  i -> i, i  i -> c, c  c -> c}

H9 5.21 使用例5.9的规则,确定下列哪些 表达式有唯一类型(假定z是复数): (a) 123 (b) 1  (z 2) (c) (1  z )  z 运算规则: int  int -> int int  int -> complex complex  complex -> complex H9 1  (z 2) :{complex} 1:{int} *: {i  i -> i, i  i -> c, c  c -> c} z*2:{complex} z:{complex} *: {i X i -> i, i X i -> c, c X c -> c} 2:{int, complex} 类型唯一

H9 5.21 使用例5.9的规则,确定下列哪些 表达式有唯一类型(假定z是复数): (a) 123 (b) 1  (z 2) (c) (1  z )  z 运算规则: int  int -> int int  int -> complex complex  complex -> complex H9 (1  z )  z:{complex} 1*z:{complex} *: {i  i -> i, i  i -> c, c  c -> c} z:{complex} 1:{int, complex} *: {i  i -> i, i  i -> c, c  c -> c} z:{complex} 类型唯一