09 結構、聯合、列舉與定義型態

Post on 12-Jul-2015

4.509 Views

Category:

Business

0 Downloads

Preview:

Click to see full reader

TRANSCRIPT

第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 上機實習課程

top related