Upload
shademoon
View
4.509
Download
0
Embed Size (px)
Citation preview
第9章 結構、聯合、列舉與定義型態
結構簡介
其它自訂資料型態
上機實習課程
2
結構宣告與存取(1)
結構的架構必須具有結構名稱與結構項目,而且必須使用關鍵字struct來建立,一個結構的基本宣告方式如下所示:
9-1 結構簡介
struct 結構名稱
{
資料型態 結構成員1;
資料型態 結構成員2;
......
};
3
在結構定義中可以使用基本的變數、陣列、指標,
甚至是其它結構成員等。
注意在定義之後的分號不可省略,這是經常忽略
而使得程式出錯的地方,以下為一個結構定義的
實際例子,結構中定義了學生的姓名與成績:
9-1 結構簡介
struct student
{
char name[10];
int score;
int ID;
};
4
在定義了結構之後,我們可以直接使用它來建
立結構物件,結構定義本身就像是個建構物件
的藍圖或模子。
而結構物件則是根據這個藍圖製造出來的成品
或模型,每個所建立的結構物件都擁有相同的
結構成員,一個宣告建立結構物件的例子如下
所示:
9-1 結構簡介
struct student s1, s2;
5
在建立結構物件之後,我們可以使用英文句號.
來存取結構成員,這個句號通常稱之為「點運
算子」(dot operator)。
只要在結構變數後加上成員運算子"."與結構成
員名稱,就可以直接存取該筆資料:
9-1 結構簡介
結構變數.項目成員名稱;
6
結構宣告與存取(2)
程式範例:結構宣告與存取的基本應用範例:
CH09_01.c
9-1 結構簡介
7
9-1 結構簡介
8
執行結果
程式解說
9-1 結構簡介
第6~11行中定義並宣告student結構的s1,s2變數。
請注意在第14行中不可以直接將字串值直接指定給
字元陣列,必須要使用strcpy()函數。
第19行使用gets()函數輸入s2.name初始值。
第24~25行中計算兩個結構變數的總分及平均。
9
結構宣告與存取(3)
程式範例:不定義結構名稱與同時指定初始值
的基本應用範例:CH09_02.c
9-1 結構簡介
10
執行結果
程式解說
9-1 結構簡介
第6~11行中不定義新的結構型態,卻宣告結構變
數,並以大括號括住來設定結構變數成員。
11
巢狀結構(1)
基本結構如下:
9-1 結構簡介
struct 結構名稱1
{
……
};
struct 結構名稱2
{
……
struct 結構名稱1 變數名稱;
……
12
將巢狀結構用以下的方式來撰寫,將內層結構
被包於外層結構之下,可省略內層結構的名稱
定義:
9-1 結構簡介
struct member
{
struct
{
char first_name[10];
char last_name[10];
} member_name;
char ID[10];
int salary;
} m1={ {"Helen","Wang"},"E121654321",35000};
13
巢狀結構(2)
程式範例:巢狀結構的基本應用範例:
CH09_03.c
9-1 結構簡介
14
執行結果
9-1 結構簡介
15
程式解說
9-1 結構簡介
第6~10行定義結構name,第12~17行定義則巢狀
結構 member。
第17行宣告了member型態的結構變數m1,並設定
初始值。
第21行輸出巢狀結構中的成員。
16
結構陣列(1)
下面這個程式碼片段將建立具有五個元素的結
構陣列:
9-1 結構簡介
struct student
{
char name[10];
int math;
int english;
};
struct student class1[3];
17
如果同時要記錄多筆相同結構資料,還是得宣
告一個結構陣列型態。宣告方式如下:
至於要存取的成員,在陣列後方加上"[索引值]"
存取該元素即可,例如:
9-1 結構簡介
struct 結構型態名稱 結構陣列名稱[元素個素];
結構陣列名稱[索引值].陣列成員名稱
18
結構陣列(2)
程式範例:結構陣列的基本應用範例:CH09_04.c
9-1 結構簡介
19
9-1 結構簡介
20
執行結果
程式解說
9-1 結構簡介
第6~11行中定義studen結構,其中包括字串name、整
數math與整數english三種資料成員。
第13~14行定義並設定3個元素的結構陣列初始值。
第21行計算數學總分及第22行計算英文總分。
第27行計算3個學生的兩科平均成績。
21
在結構陣列中的資料成員也可以宣告為陣列型
態,如果各位在結構陣列中要宣告陣列成員,
也是直接在陣列前面加上資料型態即可,如下
所示:
9-1 結構簡介
struct 結構名稱
{
……
資料型態 陣列名稱[元素個數];
};
struct 結構名稱 結構陣列名稱[元素個數;
22
結構陣列(3)
程式範例:結構陣列的陣列資料成員的宣告與
存取範例:CH09_05.c
9-1 結構簡介
23
9-1 結構簡介
24
執行結果
程式解說
9-1 結構簡介
第6~11行,定義club結構 ,結構中有name陣列資料成員。
定義並設定結構陣列初始值。
第26行輸出每一個club的陣列成員姓名字串。
25
結構與記憶體位址(1)
定義與宣告:
在結構變數m1中,其成員name與age在記憶
體中將會如下分佈:
9-1 結構簡介
struct member
{
char name[20];
int age;
};
struct member m1;
26
結構與記憶體位址(2)
程式範例:指標變數與結構成員記憶體位址宣
告與存取範例:CH09_06.c
9-1 結構簡介
27
執行結果
9-1 結構簡介
28
程式解說
9-1 結構簡介
第6~11行定義member結構。
第18行中,我們直接將m1.name指定給ptr1,這
是因為陣列名稱本身就代表記憶體位址。
第19行&運算子表示取得成員s1.age的記憶體位
址,再指定給ptr2。
29
結構與記憶體位址(3)
程式範例:結構陣列或變數的記憶體大小求取
範例:CH09_07.c
9-1 結構簡介
30
執行結果
程式解說
9-1 結構簡介
第12行整個結構陣列所佔有的記憶體容量是120個位元
組,而一個陣列元素所佔的空間是24位元,因此結構
陣列所佔空間為24*5=120。
第14行的name資料成員記憶體是20位元,第15行age
資料成員記憶體是4位元。
31
宣告方式如下:
宣告好結構型態及結構指標之後,才能間接存
取其指定結構變數的成員。如下所示:
結構指標(1) 9-1 結構簡介
struct 結構名稱 *結構指標名稱;
結構指標名稱 = &結構變數名稱;
32
例如我們可以在程式中定義如下的結構指標宣告:
9-1 結構簡介
struct member
{
char name[20];
int age;
} m1;
struct member *ptr; /* 宣告結構指標 */
ptr=&m1;
33
結構指標(2)
程式範例:結構指標的宣告與存取範例:
CH09_08.c
9-1 結構簡介
34
9-1 結構簡介
35
執行結果
程式解說
9-1 結構簡介
第13行宣告結構指標ptr,並在第25行初始化指標,
將ptr指向m1結構變數。
第27、29行是利用第一種結構指標存取方式。
第31行初始化指標,將ptr指向m2結構變數。
第33、35行是利用第二種結構指標存取方式。
36
結構指標(3)
程式範例:結構陣列與指標常數存取範例:
CH09_09.c
9-1 結構簡介
37
9-1 結構簡介
38
執行結果
程式解說
9-1 結構簡介
第14~17行定義並設定結構陣列初始值,第20、
25行以指標常數方式輸出結構陣列的資料成員。
39
結構與函數傳值呼叫(1)
結構傳值呼叫的函數宣告如下:
呼叫函數的語法如下:
9-1 結構簡介
函數型別 函數名稱(struct 結構名稱 結構變數);
{
函數主體;
}
函數名稱(結構變數);
40
結構與函數傳值呼叫(2)
程式範例:結構與傳值呼叫的函數範例:
CH09_10.c
9-1 結構簡介
41
9-1 結構簡介
42
執行結果
程式解說
9-1 結構簡介
第4~9行定義結構 ,並使這個club結構為全域性的結構型
態。
第11行結構變數傳值呼叫函數原型宣告。
第17行定義並設定結構陣列初始值。第20行呼叫函數。
第26~33定義show()函數主體,並於28、29行輸出s的資
料成員。
43
結構與函數傳值呼叫(3)
程式範例:結構與傳值呼叫calculate()函數應
用範例:CH09_11.c
9-1 結構簡介
44
9-1 結構簡介
45
執行結果
程式解說
9-1 結構簡介
第12行結構變數傳值呼叫函數calculate()的原型宣告,第17行
宣告stud結構變數,並設定結構初始值。
第19行以傳值呼叫傳遞stud變數。
第21行輸出stud變數的原來設定值,雖然在calculate()函數中
已改變Chi資料成員的值。
第31行Chi的值乘以1.3,因此在第35行輸出時的值是
60*1.3=78,但不會改變main()函數中的原值。
46
結構與函數傳址呼叫(1)
結構傳址呼叫的函數宣告如下:
呼叫函數的語法如下:
9-1 結構簡介
函數型別 函數名稱(struct 結構名稱 *結構變數);
{
函數主體;
}
函數名稱(&結構變數);
47
結構與函數傳址呼叫(2)
程式範例:結構與傳址呼叫calculate()函數的
應用範例:CH09_12.c
9-1 結構簡介
48
9-1 結構簡介
49
執行結果
程式解說
9-1 結構簡介
第12行 結構變數傳址呼叫函數的原型宣告。
第19行呼叫calculate()函數,必須使用「&」運算子。
第30~32行以第二種結構指標方式來存取資料成員,各
位也可以使用第一種方式,如(*s1).Eng=(*s1).Eng*1;。
在第35行輸出此結構變數時,已改變Chi資料成員的值,
當回到main()函數後第21行輸出時,Chi資料成員的值也
同步改變了。
50
結構與函數傳址呼叫(3)
程式範例:結構與傳址呼叫max()函數的應用
範例:CH09_13.c
9-1 結構簡介
51
9-1 結構簡介
52
執行結果
程式解說
9-1 結構簡介
第4~9行是定義全域的結構member,第10行為傳址函
數max()的原型宣告。
第20行呼叫max()函數,記得使用「&」運算子。
第36~38行執行交換運算,找出p1或p2哪一位salary資
料成員高。
53
結構與函數傳址呼叫(4)
程式範例:結構與傳址呼叫max()函數的應用
範例:CH09_14.c
9-1 結構簡介
54
9-1 結構簡介
55
執行結果
9-1 結構簡介
56
程式解說
9-1 結構簡介
第10行以傳址呼叫的函數原型宣告。
第20行定義並設定結構陣列初始值。
第22行呼叫並傳遞陣列到函數中。
第28~44行定義傳遞陣列的傳址呼叫函數。
57
結構與函數傳址呼叫(5)
程式範例:結構與傳址呼叫min()函數的應用範
例:CH09_15.c
9-1 結構簡介
58
9-1 結構簡介
59
執行結果
程式解說
9-1 結構簡介
第10行以傳址呼叫的函數原型宣告。
第17~19行定義並設定結構陣列初始值。
第21 c;61呼叫並傳遞陣列到min()函數。
第32行設定陣列第一筆元素成績為min_score。
第33~38行以for迴圈找出最小值。
60
列舉型態(1)
宣告語法如下:
9-2 其它自訂資料型態
enum 列舉型態名稱
{
列舉成員1,
列舉成員2,
……
}
enum列舉型態名稱 列舉變數1,列舉變數2…;
61
例如以下宣告:
9-2 其它自訂資料型態
enum animal
{
tiger,
monkey,
dog,
cat
}; /* 定義列舉型態 animal */
enum animal zoo1,zoo2; /* 宣告列舉型態animal的
變數 zoo1與zoo2 */
62
列舉型態(2)
程式範例:列舉型態的宣告與應用範例:
CH09_16.c
9-2 其它自訂資料型態
63
執行結果
9-2 其它自訂資料型態
64
程式解說
9-2 其它自訂資料型態
第6~10行定義一個列舉型態 animal。
第12行宣告列舉型態animal的變數 zoo1與zoo2。
第13、14行分別將zoo1、zoo2的值設定為tiger與dog。
第16行輸出各個animal列舉成員所代表的整數常數值。
65
列舉型態(3)
程式範例:列舉型態的宣告與更改初始值範例:
CH09_17.c
9-2 其它自訂資料型態
66
執行結果
程式解說
9-2 其它自訂資料型態
第7行中我們重新設定tiger的初始值,第9行中則重新設定dog的
初始值。
第13、14行將zoo1的值設定為tiger及將zoo2的值設定為dog。
67
型態定義功能(1)
宣告語法如下:
例如:
9-2 其它自訂資料型態
typedef 原資料型態 新定義型態識別字
typedef int integer;
int height=50;
integer age=120;
type char* strinng;
string s1="我是張大大"
68
型態定義功能(2)
程式範例:型態定義(typedef)的使用與宣告範
例:CH09_18.c
9-2 其它自訂資料型態
69
執行結果
程式解說
9-2 其它自訂資料型態
第4行把int定義成INTEGER,而第5行則把char*定
義成STRING。
第9~10行分別宣告score是 INTEGER型態與宣告s1
是STRING型態。
70
通常在定義結構之後,我們會使用typedef定義
結構的資料型態名稱別名,程式碼宣告就不必
每次加上struct保留字了,以方便宣告結構變
數,例如:
9-2 其它自訂資料型態
struct student
{
char name[10];
int score;
};
typedef struct student sdn; /* 定義資料型態名稱為sdn */
snd s1, s2; /* 使用snd名稱宣告結構物件s1與s2 */
71
型態定義功能(3)
程式範例:型態定義與結構型態的使用與宣告
範例:CH09_19.c
9-2 其它自訂資料型態
72
9-2 其它自訂資料型態
73
9-2 其它自訂資料型態
74
執行結果
9-2 其它自訂資料型態
75
程式解說
9-2 其它自訂資料型態
第9行定義資料型態名稱為sdn。
第15行~19行宣告snd型態的s陣列,並設定初始值。
第29~30行由於陣列是傳址方式,所以排序後的結果
會直接影響s陣列,我們只要直接於主函式中再次顯示
s的內容,即可顯示排序後的結果。
第36~49行以氣泡排序法來進行對fs陣列的排序,使用
的觀念是兩個結構物件變數若相同,則可以直接使用
指定運算子進行成員資料的複製。
76
聯合型態(1)
聯合型態的宣告方式如下:
例如以下是聯合型態的宣告:
9-2 其它自訂資料型態
union 聯合名稱
{
資料型態1 資料成員1;
資料型態2 資料成員2;
資料型態3 資料成員3;
……
}聯合變數;
union student
{
char name[10];/* 佔10bytes 空間 */
int score;/* 佔 4bytes 空間 */
};
77
聯合型態(2)
程式範例:聯合與結構型態的使用與宣告比較
範例:CH09_20.c
9-2 其它自訂資料型態
78
執行結果
9-2 其它自訂資料型態
79
程式解說
至於聯合型態的存取方式是在聯合變數後加上
小數點「.」再加上資料成員即可:
9-2 其它自訂資料型態
第4~8行宣告結構型態student1,第10~14行宣告聯合型
態student。
第18~19行s1為結構變數與s為聯合變數。
第21行輸出結構變數與聯合變數所佔位元組。
聯合物件.資料成員;
80
聯合型態(3)
程式範例:聯合型態的宣告與存取範例:
CH09_21.c
9-2 其它自訂資料型態
81
執行結果
程式解說
9-2 其它自訂資料型態
第14行宣告s為聯合變數。
第15行設定s.name初始值。
第16行存取s.name的值。
第17行設定s.score初始值。
第18行存取s.score的值。
82
上機實習課程(1)
上機實習範例:CH09_22.c
– 假設現在有以下結構型態:
– 請設計一程式來輸出結構變數desk一共佔了多
少位元組。
9-3 上機實習課程
83
9-3 上機實習課程
84
執行結果
9-3 上機實習課程
85
上機實習課程(2)
上機實習範例:CH09_23.c
– 由於陣列名稱可以利用指標常數來存取,各位
也可以指標常數方式來表示結構陣列。例如以
下student型態的結構陣列class1:
9-3 上機實習課程
struct student
{
char name[20];
int math;
int english;
};
struct student class1[5]=
{{"章成方",87,79},{"王克擎",81,100},{"林函樓",78,90},{"吳黛玲
",99,85},{"陳昭輝",90,65}};
86
9-3 上機實習課程
87
9-3 上機實習課程
88
執行結果
9-3 上機實習課程
89
上機實習課程(3)
上機實習範例:CH09_24.c
– 試設計一程式,定義一巢狀結構product,其資
料成員包含price(價格)與規格(scale),而規格
(scale)是屬於size結構的變數,由長(length)、
寬(width)與高(height)三個成員所組成。
– 在此程式中宣告及設定一個product型態變數
desk,並輸出其所有成員資料。
9-3 上機實習課程
90
9-3 上機實習課程
91
執行結果
9-3 上機實習課程
92
上機實習課程(4)
上機實習範例:CH09_25.c
– 延續上題,請設計一結構傳值呼叫函數,可傳
遞兩結構變數,並可用資料成員(長*寬*高)來比
較這兩變數的體積大小,及傳回與輸出體積較
大者的所有資料成員。
9-3 上機實習課程
93
9-3 上機實習課程
94
執行結果
9-3 上機實習課程
95
上機實習課程(5)
上機實習範例:CH09_26.c
– 延續上題,請設計一結構傳址呼叫函數,可傳
遞一結構陣列變數,如陣列元素的價格(price)
資料成員大於12000,則可享有九折優惠,並
更改price成員的值。
– 最後傳回打完折後的陣列與輸出此陣列所有元
素的資料成員。
9-3 上機實習課程
96
9-3 上機實習課程
97
9-3 上機實習課程
98
執行結果
9-3 上機實習課程
99
上機實習課程(6)
上機實習範例:CH09_27.c
– 我們可以使用結構自訂資料型態,也能使用結
構來宣告指標陣列,陣列中的每個元素,所存
放的都是指標。
– 以下程式範例中將以結構指標陣列s2的每個元
素都指向結構陣列s1的每個元素,並利用s2陣
列來進行氣泡法排序及由分數大小輸出所有陣
列元素的資料成員。
9-3 上機實習課程
100
9-3 上機實習課程
101
9-3 上機實習課程
102
執行結果
9-3 上機實習課程
103
上機實習課程(7)
上機實習範例:CH09_28.c
– 以下程式範例,將使用練習malloc()與free()這
兩個函式,首先以malloc()動態配置的方式,配
置給結構變數一個記憶體空間,並於程式結束
前,使用free() 釋放所配置的資源。
9-3 上機實習課程
104
9-3 上機實習課程
105
上機實習課程(8)
執行結果
上機實習範例:CH09_29.c
– 在動態配置記憶體空間時,最常使用的就是「串
列」(link)結構。
– 對於一個基本的串列結構,我們必須使用一個資
料欄與一個指標ptr記錄最後一個元素的位置。
9-3 上機實習課程
106
假設我們現在要新增一個元素至串列的尾端,
在程式上必須設計四個步驟:
9-3 上機實習課程
1.使用malloc()配置記憶體空間給新元素新節點使用。
2. 將原串列尾端的指標欄(next)指向新元素所在的記
憶體位置。
3.將ptr指標指向新節點的記憶體位置,表示這是新的
串列尾端。
4. 由於新節點目前為串列最後一個元素,所以將它的
指標欄(next)指向NULL。
107
9-3 上機實習課程
108
9-3 上機實習課程
109
9-3 上機實習課程
110
執行結果
9-3 上機實習課程
111
上機實習課程(9)
上機實習範例:CH09_30.c
– 以下程式範例是要說明如果於結構型態內宣告
指標成員,如何存取此指標變數的方法。
– 當結構成員宣告為指標變數,在實體結構物件
中則以小數點「.」存取指標變數
9-3 上機實習課程
112
執行結果
9-3 上機實習課程
113
上機實習課程(10)
上機實習範例:CH09_31.c
– 延續上題,以下程式範例是說明如果於結構型
態內宣告指標成員,而且當必須結構指標來存
取資料成員時時,則必須以(->)運算子存取指標
成員及其他資料成員。
9-3 上機實習課程
114
9-3 上機實習課程
115
執行結果
上機實習範例:CH09_32.c
– 在程式中若以數值表示顏色,意義上較不清楚,
這時可以使用「列舉常數」(enumeration
constants)來自訂列舉型態。
– 若要設定列舉的初值,則直接於宣告的同時指
定其值就可以了,如下所示:
9-3 上機實習課程
enum colors { RED = 1, ORANGE, YELLOW,
GREEN, BLUE, INDIGO, PURPLE };
116
執行結果
9-3 上機實習課程
117
上機實習課程(11)
上機實習範例:CH09_33.c
– 以下程式範例是將結構指標指向陣列,並利用
結構指標的加法運算存取陣列中所有元素的資
料成員。
9-3 上機實習課程
118
執行結果
9-3 上機實習課程
119
上機實習課程(12)
上機實習範例:CH09_34.c
– 以下程式範例中由於要將結構資料當作傳回值,
因此必須在該函式中先建立結構資料變數,然
後輸入結構成員的值,並將所輸入的值傳回呼
叫的敘述句。
9-3 上機實習課程
120
9-3 上機實習課程
121
執行結果
9-3 上機實習課程