Transcript CHppt\ch4
第四章
資料型態
陳維魁 博士
[email protected]
儒林圖書公司
1
大綱
資料型態的定義
資料型態的分類
靜態與動態型態檢驗
型態強制轉換
型態相等性
精選習題
2
資料型態的定義
資料型態是指一群個體(object)以及作用在
這群個體上的運算
近代高階語言均要求程式設計師在設計程
式時,必須對程式段中所有使用到的變數
宣告資料型態—外顯式型態法
增加程式的可讀性、可靠性及可維護性
3
資料型態的分類
基本資料型態
數字
整數(integer):2Byte-32768~32767
實數(real)可具有小數點--浮點數(floating point
number)
字元
布林資料型態
列舉式資料型態
指標資料型態
結構性資料型態
4
基本資料型態
數字
整數(integer)
若整數佔用的記憶體空間為二個位元組,則其範圍將
介於–32768與32767之間
實數(real)--浮點數(floating point number)
實數代表可具有小數位數之數值
優點
可加快程式執行的速度
缺點
由於每種機器所允許的數值的有效範圍皆不同,所以
相同的計算在不同的機器上運算所得的結果可能不盡
相同
5
整數表示法
符號大小值法-首位元作為符號位元,0表示正
,1表示負
1的補數法-負整數以正整數的1的補數來表示
2的補數法-負整數以正整數的1的補數來表示
浮點數
大多數實數只能表達近似值
浮點數記憶格式包含三個欄位:符號欄位、指
數、小數。實數佔32位元、倍精實數64位元
實數儲存-轉成二進位-正規化(小數點移到最左
6
邊非0位元前,以指數紀錄)
計算順序
1. 運算子的優先順序
2. 結合性:左結合由左向右計算;右結合由右
向左計算
3. 括號:加上括號的優先高於未加括號;多
層的括號,內層優先
7
運算元的計算
運算元的順序主要關係在邊際效應(side
effects)
邊際效應:副程式執行時候改變了不屬於該
副程式的資料
8
邊際效應
Procedure sub1
var A:integer;
function FUN (x)
begin
FUN:=x div 2;
A:=20;
end;
Begin
A:=10;
A:=A+FUN(A);…先取出A=10計算,或先執行FUN(10)結果不同
…
End;
9
避免邊際效應
不允許函數的運用
定義運算元的順序
限制函數不可以改變其他運算元
10
多意
隨著運算元(operand)型態的不同,運算子(operator)作不同
的計算處理即稱之為多意(polymorphism)
範例
假設A與B為二個數值變數,當執行A+B敘述時
常見情形
若A、B為整數時則A+B是做整數的加法運算
若A、B為實數時則A+B是做實數的加法運算
前面所說明的A+B敘述之運算,運算元A與B之型態都是相
同的,但是事實上,運算元A與B之型態可能是不相同的,譬
如A是整數而B是實數,此時必須將A與B之型態一致化之後,
才能進行運算
“型態一致化”
寬化(widening)
窄化(narrowing)
11
基本資料型態
字元
字元所佔用的記憶體空間為一個位元組(byte),如英文
字母、阿拉伯數字或+、-、×、/等特殊符號均可視為
一個字元
布林資料型態
布林值可能的值為true與false二種
不同的高階語言對布林值在處理的方式來說其作法不
一定相同
C語言及C++語言允許布林值與數值混合計算,只要數
值非0,在C語言及C++語言中將其視為true,但若數值
為0則視為false
12
布林資料型態範例
底下的C程式會讓變數X之值為何?
if(((3>2)&&(2<2))∣∣(5==6)∣∣((5>4)&& 3))X=3;else X=4;
13
“and” 與條件敘述的對應
and 對應的敘述
if x then y else false
X y
and
0 0
0
0 1
0
1 0
0
1 1
1
14
“or” 與條件敘述的對應
X
0
0
1
1
or 對應的敘述
if x then true else y
y
0
1
0
1
or
0
1
1
1
15
“not” 與條件敘述的對應
not 對應的敘述
if x then false else true
X
0
1
not
1
0
16
“imply” 與條件敘述的對應
X
0
0
1
1
imply 對應的敘述
if x then y else true
y
0
1
0
1
imply
1
1
0
1
17
“equivalence” 與條件敘述的對應
equivalence 對應的敘述
if x then y else (not y)
若兩者相等則true
X
0
0
1
1
y equivalence
0
1
1
0
0
0
1
1
18
“exclusive or” 與條件敘述的對應
exclusive or 對應的敘述
if x then (not y) else y
X
0
0
1
1
y
0
1
0
1
exclusive or
0
1
1
0
19
列舉式資料型態(enumerated data type)
定義
將需要的資料一一定義與列舉出來
假設一班級有學生七人分別是John,Mary,
May,Peter,Jacky,Jany與Tom
用C語言將此份資料定義成一列舉式資料型態
之語法如下:
enum Student {John, Mary, May, Peter, Jacky, Jany, Tom};
以Pascal語言來處理同一份資料則其作法如下:
type Student = (John, Mary, May, Peter, Jacky, Jany, Tom);
20
列舉式資料型態
Pascal的列舉資料型態是純量型態的一種
可以再定義子區間(sub-range)的資料型
態
Type Sub_student= Mary..Jany;
用法
指定敘述
陣列的註標(index)
FOR-LOOP的控制變數
布林運算式中的比較項
21
例如
Type seasons=(Spring,Summer,Fall,Winter);
Var P, Q, R: seasons;
P:= Spring; --指定敘述
Q:= Fall;
--指定敘述
If P=Q then R:=Summer else R:= Winter –布林運算
比較項
For i:=Spring to Winter do –FORLOOP控制
begin
22
指標(pointer)資料型態
指標是參考(reference)物體的一種方式
10
100
point er
有一指標指到記憶體位址為10之處,而其內容為100
指標變數的值
記憶體位址
NIL
23
指標資料型態
優點
彈性較大,可以任意存取記憶體空間中之資料
若有多個串列中具某筆相同的資料,則可僅配置一個
記憶體空間給該筆資料使用,每個串列再用指標指到
該筆資料即可
缺點
安全性較差
存取速度可能較慢
可能造成懸置引用(dangling reference) 的問題
可靠性(reliability)較差
24
Pascal 的指標資料型態範例
var ptr : ^ integer;
其中“ptr”代表位址(address)
“ptr^”則代表值(value)
Pascal的指標變數函式
new()
配置新的記憶體空間供指標變數使用
dispose()
歸還記憶體空間給系統
25
C /C++ 的指標資料型態範例
“*”代表取值運算子
“&”代表取址運算子
範例
int *x,y;
x是指標變數,y是一般變數
“x”及“&y”代表位址(address)
“*x”及“y”則代表值(value)
26
C/C++ 指標資料型態與陣列資料之關連
C/C++語言的陣列起始註標(index)為0
陣列的第一個元素之位址即陣列之起始位
址
範例
int a[5];
int *ptr; --指標變數 ptr代表位址, *ptr表值
“ptr = a;”與“ptr = &a[0];”二個敘述的邏輯意義
是相同的
27
指標使用不當所可能造成的問題
懸置引用(dangling reference)
懸置指標(dangling pointer)
懸置物件(dangling object)
28
懸置引用
指標變數指到一個已經不存在的記憶體空
間
如Pascal語言中,x是一個指標變數,當執
行了dispose(x)後,若想引用x,則將造成
懸置引用現象
29
懸置指標
指標指到一個不存在任何有意義資訊的記
憶體空間
一般程式語言中會導致懸置指標的一種常
見情形是某一個呼叫程式中的指標變數指
向被呼叫程式中的區域變數,當被呼叫程
式執行結束後,則區域變數對應的記憶體
空間中的資料將會被清除,如此一來呼叫
程式中的指標變數將成為“懸置指標”
30
懸置物件
一個仍然存放資訊的記憶體空間,可是已
沒有辦法可存取這個空間,則此空間便被
稱為懸置物件
31
結構性資料型態
定義
將具關連性的資料結合成一個個體的方法,即稱之為
結構性資料型態
種類
陣列
記錄
聯合資料型態
字串
集合
可變長度資料型態
32
陣列
陣列主要是由陣列的名稱,維度,元素型態
以及索引等元件組成
主要限制
陣列元素必須存放在連續的記憶體空間中(但
SMALLTALK語言例外)
陣列元素的型態必須完全相同
33
陣列種類
固定界限陣列
指陣列的元素個數是固定的
必須採用靜態儲存區配置法(static storage allocation)
PASCAL、C及C++;
動態界限陣列
指陣列的元素個數是可變動的
採用動態儲存區配置法(dynamic storage allocation)
ALGOL
34
關於陣列的三個重要問題
計算陣列元素個數(假設為n個元素)
計算陣列元素佔用之記憶體空間總量
作法為分別計算陣列中各個維度元素的個數再
相乘即可。
假設陣列個別元素佔用之記憶體空間為w,則
陣列元素佔用之記憶體空間總量為n×w)
計算陣列中特定元素之記憶體位址
35
陣列描述器(array descriptor)
包括
陣列名稱
元素的型態
元素的長度
陣列的起始位址
維度
各個維度的上、下限
36
陣列儲存方式
以列為優先
以行為優先
在編排陣列中元素之順序時,最右邊的索引值
先變(加1),再向左進位
在編排陣列中元素之順序時,最左邊的索引值
先變(加1),再向右進位
以列為優先法較符合人類的習慣
除了FORTRAN採用以行為優先法外,絕
大部份的高階語言均是採用以列為優先法
37
四種陣列分類法
靜態陣列(static array)
PASCAL語言在主程式段中宣告的陣列,其元
素個數在執行前決定且記憶體空間在執行前配
置
半靜態陣列(semi-static array)
PASCAL語言在副程式段中宣告的陣列,其元
素個數在執行前決定且記憶體空間在執行時配
置
38
四種陣列分類法
半動態陣列(semi-dynamic array)
ADA語言中宣告的陣列,其元素個數在執行
時決定且記憶體空間在執行時配置,但一旦配
置即不可更改
動態陣列(dynamic array)
ALGOL語言中宣告的陣列,其元素個數在執
行時決定且記憶體空間在執行時配置,但可更
改
39
記錄
是由固定數目,但型態可以不同的元素所組成
屬性(attributes)
欄位的名稱
欄位的資料型態
欄位的個數
一般來說記錄的欄位(field)的數目是固定的,但
Pascal 提供了變異記錄(variant record)資料型態,
它的欄位數目就是可變動的
40
記錄實例
Pascal語言實例
Type StudentData = record
Name : string〔30〕;
Age : integer;
PhoneNo : string[10];
Sex : char;
Address : string〔50〕
end;
41
記錄引用的方式
函數式記號
由 Knuth所提出
ALGOL 68採用
語法為“欄位名稱(記錄名稱)”
限定名稱格式
Pascal、Ada、PL/1、C及Modula-2等語言採用
語法為“記錄名稱.欄位名稱”
Pascal可利用with敘述簡化
42
聯合資料型態(union data type)
意義
對同一個記憶體的空間而言在不同的執行時間
可存放不同型態的值
提供聯合資料型態的語言
Pascal--變異記錄(variant record)
ADA--變異記錄
Fortran --“EQUIVALENCE”敘述
43
變異記錄重要範例
Pascal:
type T= record
price : real;
case sex : (M, F) of
M : (age : integer);
F : (blood : (A, B, O, AB))
end;
end;
請問以上 Pascal 之 Variant record type 有什麼不安全的地方?(國家考試
常見考題)
44
Age blood共用一個記憶體空間
當sex=M,執行age:=20
如果同時執行blood:=‘b’,系統也接受
因為兩個存在同一個記憶體空間,應該存
放age資料,卻變成存了blood
45
變異記錄重要範例
試問 Ada 程式語言如何避免 Pascal 語言
中變異記錄(Variant record)的不安全性
(insecurity)?
ADA會檢查欄位的合法性
46
Fortran範例
INTEGER X
REAL Y
EQUIVALENCE (X, Y)
變數x和y占用同一個記憶體空間
47
字串(string)
定義
由一組字元(character)所組成之集合,便 稱之為
字串
PL/1語言首先提供了對字串的運算處理功
能
SNOBOL語言的字串處理能力十分強大,
可直接執行“型態比對”(pattern match)動
作
48
三種不同的字串處理法
宣告具有固定之長度
PASCAL是採用
利用編譯時期描述子(compile-time descriptor)
描述子會記錄 長度、位址
49
字串的長度可變動,但有範圍的限制
PL/1採用
利用執行時期描述子(run-time descriptor)
描述子紀錄最大長度、目前長度、位址
50
對字串的長度沒有任何限制
SNOBOL採用
linked list連接串列方式:變長或縮短較易處理,
但是需要較多記憶空間,運算缺乏效率
Adjacent memory相鄰記憶體:運算較快、節省
空間,但是變長或縮短不容易處理
51
集合資料型態
用來儲存沒有順序關係的資料
由PASCAL語言所首創
在PASCAL語言中空集合以“[ ]”表示,
“+”代表聯集運算、“*”代表交集運算,
而“-”則代表差集運算
52
可變長度資料結構
又稱為動態資料結構
資料的大小在編譯階段未被設定,執行時得以改變
靜態資料結構(static data structure)是指資料的大
小在編譯階段被設定,執行時不得改變
常見的可變長度資料結構
鏈結串列(linked list)
佇列(queue)
堆疊(stack)
樹(tree)
53
鏈結串列
鏈結串列為最簡單的動態資料結構
Head
P
R
nil
優點
Q
插入或刪除一個節點非常容易
當鏈結串列被破壞時,較易恢復
缺點
增加了一個指標欄位較浪費儲存區空間
54
佇列(queue)
FIFO (First In First Out)
佇列結構在電腦上的應用
作業系統(OS)工作排程(job scheduling)
中斷處理的等候佇列(waiting queue)
Input / Output Queue
55
堆疊(stack)
主要運算有五種
PUSH, POP, CREATE, TOP, ISEMPTY
堆疊結構在電腦上的應用
副程式的呼叫,儲存活動記錄(activation
record)
Macro call within macro call 的製作須堆疊
在編譯程式中堆疊可幫助分析指令,如算術運
算子的值
中斷處理
56
樹(tree)
定義
是由一個或多個節點(node)構成
其中一個節點稱為樹根(root)
除去樹根節點,剩下的節點可分為n個互斥(n≧0)集合,
分別為T1,T2,…,Tn,而Ti,1≦i≦n,本身也是樹
-T的子樹(sub-tree)
特性
樹是連通圖(connected graph)
樹中不允許迴路(cycle)
假設樹中有x個節點,y個邊,則x = y+1
57
型態檢驗
分類
靜態型態檢驗
動態型態檢驗
58
靜態型態檢驗(static type checking)
定義
優點
產生較有效率的目的碼(object code)
缺點
變數的型態在編譯時即已決定
欠缺彈性
範例
Pascal、C、C++、Java等語言採用此法
59
動態型態檢驗(dynamic type checking)
定義
優點
彈性較佳
缺點
變數的型態在執行時決定
處理過程較複雜
範例
APL、Smalltalk、Lisp、Prolog等語言採用此
法
60
型態強制轉換(coercion)
定義
將某一型態的值強制轉換成為另一種型態之值
種類
拓寬法(widening)
將某一型態的值轉換為另一型態,而值不會改變
者稱之。
縮窄法(narrowing)
將某一型態的值轉換為另一型態,而值可能會改
變者稱之。
61
強制型態語言(strongly typed language)
條件
在編譯時變數的型態可被決定
在編譯時可檢查同一運算式中,所有變數的相
容性
若允許同一記憶體空間在不同時刻儲存不同型
態之值時,必須能確保其安全性
62
型態相等性
名稱相等法(name equivalence)
結構相等法(structure equivalence)
若變數用相同型態名稱宣告或一起宣告即滿足
名稱相等法
變數的各項元件皆相等,即滿足結構相等法
陣列元素則應考慮維度,若二陣列元素個數相
同,但維度不同則視為不滿足結構相等法
宣告相容性(declaration equivalence)
變數必須一起宣告始滿足宣告相容性
63
範例
Type
vector=array[1..10] of integer;
var
a: vector:
b, c:array[1..10] of integer;
d: vector;
結構相等法: abcd都滿足
名稱相等法: a與d b與c
宣告相容性: b與c滿足
64
精選習題
何謂欠位(Underflow),溢位(Overflow)?
(1) Underflow:
指一個運算式經過電腦的計算後所得到的結果,比
電腦所能儲存的最小值還小的現象,導致電腦無法
貯存該值,此種情形稱之為Underflow。
(2) Overflow:
指一個運算式經過電腦的計算後所得到的結果,比
電腦所能儲存的最大值還大的現象,導致電腦無法
貯存該值,此種情形稱之為Overflow。
65
練習
下列程式,可能印出的答案
Int fun(int*k)
{*k+=2;
return 2*(*k)+1; }
Void main()
{int i=10, dat;
dat=fun(&i)+I;
printf(“%d”, dat);
66
Ans
非函數運算元先取出
dat=fun(&i)+1=fun(&i)+10=25+10=35
先進入函數運算
dat=fun(&i)+i=25+i=25+12=37
67
(1) 試寫出Pascal語言裡的結構化資料型態
有那些?
(2) 試寫出Pascal語言裡的五種純量型態?
(1) 集合(set),記錄(record),陣列(array),字串(string)與檔
案(file)。
(2) 整數(integer),實數(real),字元(char),布林值
(boolean),列舉式資料型態(enumerated data type)與子範圍
(subrange)。
68
6.
假設存在一個二維陣列A[1...u1,1...u2],而每個元素在記憶體中佔2 Bytes,已知
A[6,2]的存放位址為204010,A[3,4]的存放位址為209410;
(a)
A陣列在記憶體中的儲存是否為column-major方式?
(b)
A[1,1]之存放位址為何?
(c)
u1=?
(a)[6,2]在第二列,[3,4]在第四列,如果是列優先,則[3,4]的位址會在前面,所以不是列
優先
1 [1,1] 2 [1,2] 3 [1,3] 4
1 [1,1]
5
6
….
[1,u2]
4 [1,2] [1,3]
2 [2,1] 5
3 [3,1] 6
(b)2000
(c)15
69
7. 說明Fortran語言中,two-dimensional array (如
DIMENSION A(3,4))在記憶體(memory)內存放的方
式。
Fortran陣列元素在memory中之儲存方式是以
column major為主。如DIMENSION A(3,4)依以下順
序存放
A(1,1),A(2,1),A(3,1),A(1,2),A(2,2),A(3,2),
A(1,3),A(2,3),A(3,3),A(1,4),A(2,4),A(3,4)。
70
試比較linked list與sequential list的區別。
項目
(1)佔用memory
(2)memory使用率
(3)insert/delete
(4)join/seperate
(5)彈性
(6)隨機存取
(7)sort/search
sequential list
linked list
少
多
低
高
慢
快
慢
快
小
大
快
慢
快
慢
71
說明C語言中會導致懸置指標的兩種情況
(1) 若同時有多個指標指向同一個記憶體空間,若某一個指
標將此記憶體空間中的資料清除,如此一來其他指標將成為
“懸置指標”。
(2) 某一個呼叫程式中的指標變數指向副程式中的區域變數
,當副程式執行結束後,則區域變數對應的記憶體空間中的
資料將會被清除,如此一來呼叫程式中的指標變數將成為“
懸置指標”。
72
練習
16. 一陣列(Array)被以橫列為主的順序存放在記憶體內,每
個陣列佔用四個單位的記憶體,若起始位置是100,下列宣告
中所列元素的存放位置為何?
(1) var A:array[-100..1,1..100] 求 A[1,12]的位址
(2) var A:array[5..10,-10..20] 求 A[5,-5]的位址
73
Ans
(1) Loc(A[1,12])
=100+4×[(1-(-100)) ×(100-1+1)+(12-1)]
=40544
(2) Loc(A[5,-5])
=100+4×[(5-5)×(20-(-10)+1)+(-5-(-10))]
=120
74
17. 請以圖形表示下列陣列的Descriptor. integer array A:〔1..10,0..5〕
陣列名稱
元素型態
元素長度
陣列起始位址
維度
下限1
上限1
下限2
上限2
A
integer
w
2
-1
10
0
5
75
假設
Type Q=array〔1..100〕 of real;
Var
w:Q;
x:array〔301..400〕 of real;
y,z:array〔301..400〕 of real;
(1) 請問有那些變數為結構等價的?
(2) 請問有那些變數為名稱等價的?
(1)
(2)
結構等價:w=x=y=z
名稱等價:y=z
76
練習
寫出下列程式執行結果
Main(){
int a,b,c,d,e;
a=b=c=d=e;
a+=b-=c*=d=e+=2;
printf(“%d %d %d%d%d\n”,a,b,c,d,e);
a+=(b+=c)+(e-=2)-1;
printf(“%d %d %d%d%d\n”,a,b,c,d,e);
}
77
Ans
結果
-9 -12 15 5 5
-4 3 15 5 3
78