1 / 28

Chapter 9

Chapter 9. 結構 (Structure). 什麼是結構?. 目前的資料型態 (int, char, float, …) 夠用嗎? 陣列能代表同種型態的多個變數,但不同型態的多個變數怎麼宣告? 多個不同型態的陣列 在資料的整體性來說太過混亂 彼此間的關係互動,較容易疏忽 使用結構性的資料型態 有規則、架構,容易分析 容易控制,互動性較高. 結構範例 (1/2). 欲建立死黨通訊錄,應該要包括: 姓名(綽號)、地址、電話 … 陣列方式: 姓名陣列、地址陣列、電話陣列 … 難以對應,沒架構性 結構方式: 編號: 姓名、地址、電話 ….

effie
Download Presentation

Chapter 9

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Chapter 9 結構 (Structure)

  2. 什麼是結構? • 目前的資料型態(int, char, float, …)夠用嗎? • 陣列能代表同種型態的多個變數,但不同型態的多個變數怎麼宣告? • 多個不同型態的陣列 • 在資料的整體性來說太過混亂 • 彼此間的關係互動,較容易疏忽 • 使用結構性的資料型態 • 有規則、架構,容易分析 • 容易控制,互動性較高

  3. 結構範例 (1/2) • 欲建立死黨通訊錄,應該要包括: • 姓名(綽號)、地址、電話… • 陣列方式: • 姓名陣列、地址陣列、電話陣列… • 難以對應,沒架構性 • 結構方式: • 編號: • 姓名、地址、電話…

  4. 結構範例 (2/2) • 陣列方式 • 結構方式 仁齋XXX室 火車站旁 胖子 老外 03-5715131 28825252 國宅 大頭 0204123456

  5. 結構的定義 (1/2) • struct 結構名稱 {資料型態 結構元素1;資料型態 結構元素2;          .......資料型態 結構元素n; }; • Ex: • struct addrbook{    char name[20];    char addr[60];    int phone[20];};

  6. 結構的定義 (2/2) • 宣告的變數種類與數目並不設限。 • 宣告結構型態,並不佔用記憶體,只有宣告。要使用他,必須宣告一個這種型態的變數來用。 • 一樣有變數範圍(scope)的限制,在哪個位置宣告的,就有相對應的有效範圍。 • 結構之中之變數型態亦可使用結構型態,仍可包含自己或其他以定義之結構。 • 結構的大小取決於所有組成的元素。

  7. 結構型態變數的宣告 • 直接在定義時宣告 • struct 結構名稱 {資料型態 結構元素1;資料型態 結構元素2;          .......資料型態 結構元素n; } xxx, a[30], *ptr; • 以struct為型態宣告 • 在宣告前該 struct 必須定義過,定義在程式的開頭 • struct 結構名稱 xxx, a[30], *ptr;

  8. 結構的使用 • 結構成員之使用方式:經由位址或名稱 • 位址: • ->: (結構之位址)->成員 • ptr->name • (&a)->name • &a一定要括號,因為運算優先權 ->比 &高 • 名稱: • .:(結構名稱).成員 • a.name • (*ptr).name • *ptr一定要括號,因為運算優先權 .比 * 高

  9. 結構範例 (1/2) #include <stdio.h> #include <string.h> struct addrbook{ //定義addrbook型態變數 char name[20]; char addr[60]; char phone[20]; }; int main(void) { struct addrbook a; //宣告一個addrbook型態的變數 struct addrbook *ptr; //宣告一個addrbook型態的指標 strcpy(a.name, "clsu"); strcpy(a.addr, "EECS Building 820R"); strcpy(a.phone, "4158"); ptr = &a; //將addrbook型態的指標指到同型態的變數 a

  10. 結構範例 (2/2) printf("sizeof(a): %d, sizeof(&a): %d\n", sizeof(a), sizeof(&a)); printf("sizeof(ptr): %d, sizeof(*ptr): %d\n", sizeof(ptr), sizeof(*ptr)); printf("a.name: %d, a.addr: %d, a.phone: %d\n", sizeof(a.name), sizeof(a.addr), sizeof(a.phone)); printf("a.: %s, %s, %s\n", a.name, a.addr, a.phone); printf("(&a)->: %s, %s, %s\n", (&a)->name, (&a)->addr, (&a)->phone); printf("ptr->: %s, %s, %s\n", ptr->name, ptr->addr, ptr->phone); printf("(*ptr).: %s, %s, %s\n", (*ptr).name, (*ptr).addr, (*ptr).phone); return 0; } sizeof(a): 100, sizeof(&a): 4 sizeof(ptr): 4, sizeof(*ptr): 100 a.name: 20, a.addr: 60, a.phone: 20 a.: clsu, EECS Building 820R, 4158 (&a)->: clsu, EECS Building 820R, 4158 ptr->: clsu, EECS Building 820R, 4158 (*ptr).: clsu, EECS Building 820R, 4158

  11. 在結構中使用其他結構 • 結構是一種資料型態的定義,用來表示多樣的資料 • 他的成員可以包括其他資料型態,當然也可包括已定義的結構(包含自己本身) • 如果於結構中某一筆資料又可分成其他細項,這樣可用另一結構來表示 • 若結構成員中所表示的是一個與自己相同結構,則可寫成自己本身,例如:鏈結串列(linked list)

  12. 結構中有結構之範例 (1/3) #include <stdio.h> #include <string.h> struct address{ //定義address的結構 int town; int road; int num; }; struct addrbook{ //定義addrbook的結構 char name[20]; struct address addr; //addr本身是另一結構 char phone[20]; }; int main(void) { struct addrbook a; struct addrbook *ptr;

  13. 結構中有結構之範例 (2/3) strcpy(a.name, "clsu"); a.addr.town = 1; //定義addr的內容 a.addr.road = 3; //兩層結構 a.addr.num = 36; strcpy(a.phone, "4158"); ptr = &a; printf("sizeof(a): %d, sizeof(&a): %d\n", sizeof(a), sizeof(&a)); printf("sizeof(ptr): %d, sizeof(*ptr): %d\n", sizeof(ptr), sizeof(*ptr)); printf("a.name: %d, a.addr: %d, a.phone: %d\n", sizeof(a.name), sizeof(a.addr), sizeof(a.phone)); printf("a.: %s, town:%2d road:%2d num:%2d, %s\n", a.name, a.addr.town, a.addr.road, a.addr.num, a.phone); printf("(&a)->: %s, town:%2d road:%2d num:%2d, %s\n", (&a)->name, (&a)->addr.town, (&a)->addr.road, (&a)->addr.num, (&a)->phone); name addr town phone road num

  14. 結構中有結構之範例 (3/3) printf("ptr->: %s, town:%2d road:%2d num:%2d, %s\n", ptr->name, (&ptr->addr)->town, (&ptr->addr)->road, (&ptr->addr)->num, ptr->phone); printf("(*ptr).: %s, town:%2d road:%2d num:%2d, %s\n", (*ptr).name, (*ptr).addr.town, (*ptr).addr.road, (*ptr).addr.num, (*ptr).phone); return 0; } 執行結果: sizeof(a): 52, sizeof(&a): 4 sizeof(ptr): 4, sizeof(*ptr): 52 a.name: 20, a.addr: 12, a.phone: 20 a.: clsu, town: 1 road: 3 num:36, 4158 (&a)->: clsu, town: 1 road: 3 num:36, 4158 ptr->: clsu, town: 1 road: 3 num:36, 4158 (*ptr).: clsu, town: 1 road: 3 num:36, 4158

  15. 結構與函式 • 結構亦是一種變數,所以也可以在函數間傳遞 • 呼叫者與被呼叫之函式的型態要一致 • struct 對應 struct • struct 成員對應該成員的資料型態 • struct 的指標 對應 struct 的指標

  16. 結構傳遞範例 (1/3) #include <stdio.h> #include <string.h> struct address{ int town; int road; int num; }; struct addrbook{ char name[20]; struct address addr; char phone[20]; }; void dump(struct addrbook a){ //以addrbook型態之變數接收 struct addrbook *ptr; //宣告addrbook型態之指標 ptr = &a; //將宣告之指標指到接收到的 a printf("sizeof(a): %d, sizeof(&a): %d\n", sizeof(a), sizeof(&a));

  17. 結構傳遞範例 (2/3) printf("sizeof(ptr): %d, sizeof(*ptr): %d\n", sizeof(ptr), sizeof(*ptr)); printf("a.name: %d, a.addr: %d, a.phone: %d\n", sizeof(a.name), sizeof(a.addr), sizeof(a.phone)); printf("a.: %s, town:%2d road:%2d num:%2d, %s\n", a.name, a.addr.town, a.addr.road, a.addr.num, a.phone); printf("ptr->: %s, town:%2d road:%2d num:%2d, %s\n", ptr->name, (&ptr->addr)->town, (&ptr->addr)->road, (&ptr->addr)->num, ptr->phone); } int main(void) { struct addrbook a; strcpy(a.name, "clsu"); a.addr.town = 1; a.addr.road = 3;

  18. 結構傳遞範例 (3/3) a.addr.num = 36; strcpy(a.phone, "4158"); dump(a); //傳遞addrbook型態之變數 return 0; } 執行結果: sizeof(a): 52, sizeof(&a): 4 sizeof(ptr): 4, sizeof(*ptr): 52 a.name: 20, a.addr: 12, a.phone: 20 a.: clsu, town: 1 road: 3 num:36, 4158 ptr->: clsu, town: 1 road: 3 num:36, 4158

  19. 結構指標傳遞範例 (1/3) #include <stdio.h> #include <string.h> struct address{ int town; int road; int num; }; struct addrbook{ char name[20]; struct address addr; char phone[20]; }; void dump(struct addrbook *ptr){ //用addrbook型態的指標接收 struct addrbook a; //宣告一個addrbook型態的變數 a = *ptr; printf("sizeof(a): %d, sizeof(&a): %d\n", sizeof(a), sizeof(&a));

  20. 結構指標傳遞範例 (2/3) printf("sizeof(ptr): %d, sizeof(*ptr): %d\n", sizeof(ptr), sizeof(*ptr)); printf("a.name: %d, a.addr: %d, a.phone: %d\n", sizeof(a.name), sizeof(a.addr), sizeof(a.phone)); printf("a.: %s, town:%2d road:%2d num:%2d, %s\n", a.name, a.addr.town, a.addr.road, a.addr.num, a.phone); printf("ptr->: %s, town:%2d road:%2d num:%2d, %s\n", ptr->name, (&ptr->addr)->town, (&ptr->addr)->road, (&ptr->addr)->num, ptr->phone); } int main(void) { struct addrbook a; struct addrbook *ptr; ptr = &a; strcpy(a.name, "clsu");

  21. 結構指標傳遞範例 (3/3) a.addr.town = 1; a.addr.road = 3; a.addr.num = 36; strcpy(a.phone, "4158"); dump(ptr); //傳遞addrbook型態的指標 return 0; } 執行結果: sizeof(a): 52, sizeof(&a): 4 sizeof(ptr): 4, sizeof(*ptr): 52 a.name: 20, a.addr: 12, a.phone: 20 a.: clsu, town: 1 road: 3 num:36, 4158 ptr->: clsu, town: 1 road: 3 num:36, 4158

  22. 指標跟回傳值 (1/3) #include <stdio.h> // 回傳值跟指標的關係,三種不同的回傳方式 struct PHONE{ //定義PHONE char country[5]; char region[5]; char tel[20]; char ext[6]; }; typedef struct ADDRBK{ //定義 ADDRBK char name[20]; struct PHONE tel; //tel 是結構 int age; } *ADDRBKPTR; //typedef struct ADDRBK *ADDRBKPTR; struct ADDRBK modify1(struct ADDRBK entry) { entry.age ++; return entry; }

  23. 指標跟回傳值 (2/3) int modify2(struct ADDRBK entry) { entry.age ++; return entry.age; } void modify3(ADDRBKPTR ptr) { ptr->age++; } int main(void) { struct ADDRBK person = {"clsu", {"886","3","5715131","4128"},27}; printf("%s %s-%s-%s-%s %d\n", person.name, person.tel.country, person.tel.region, person.tel.tel, person.tel.ext, person.age); person = modify1(person); //接受一整個結構 printf("%s %s-%s-%s-%s %d\n", person.name, person.tel.country, person.tel.region, person.tel.tel, person.tel.ext, person.age); person.age = modify2(person); //只回傳修改的成員

  24. 指標跟回傳值 (3/3) printf("%s %s-%s-%s-%s %d\n", person.name, person.tel.country, person.tel.region, person.tel.tel, person.tel.ext, person.age); modify3(&person); //模擬 call by reference printf("%s %s-%s-%s-%s %d\n", person.name, person.tel.country, person.tel.region, person.tel.tel, person.tel.ext, person.age); return 0; } 執行結果: clsu 886-3-5715131-4128 27 clsu 886-3-5715131-4128 28 clsu 886-3-5715131-4128 29 clsu 886-3-5715131-4128 30

  25. 暱稱 (typedef) • 人有暱稱,C語言中也可以取暱稱 • 胖子、大頭、老外 … • 每次使用 struct 宣告太長,不人性,我們可以使用typedef 幫他取暱稱 • typedef struct 結構名稱 暱稱; • typedef struct{…} 暱稱; • 宣告時只需寫暱稱即可 • 暱稱 xxx, a[30], *ptr;

  26. typedef的範例 (1/3) #include <stdio.h> #include <string.h> struct address{ int town; int road; int num; }; typedef struct{ char name[20]; struct address addr; char phone[20]; } Add; //幫addrbook取暱稱 void dump(Add *ptr){ //用暱稱來接收 Add a; //用暱稱來宣告 a = *ptr; printf("sizeof(a): %d, sizeof(&a): %d\n", sizeof(a), sizeof(&a));

  27. typedef的範例 (2/3) printf("sizeof(ptr): %d, sizeof(*ptr): %d\n", sizeof(ptr), sizeof(*ptr)); printf("a.name: %d, a.addr: %d, a.phone: %d\n", sizeof(a.name), sizeof(a.addr), sizeof(a.phone)); printf("a.: %s, twon:%2d road:%2d num:%2d, %s\n", a.name, a.addr.town, a.addr.road, a.addr.num, a.phone); printf("ptr->: %s, twon:%2d road:%2d num:%2d, %s\n", ptr->name, (&ptr->addr)->town, (&ptr->addr)->road, (&ptr->addr)->num, ptr->phone); } int main(void) { Add a; //用暱稱宣告addrbook型態的變數 Add *ptr; //用暱稱宣告addrbook型態的指標 ptr = &a; strcpy(a.name, "clsu");

  28. typedef的範例 (3/3) a.addr.town = 1; a.addr.road = 3; a.addr.num = 36; strcpy(a.phone, "4158"); dump(ptr); //傳遞addrbook型態的指標 return 0; } 執行結果: sizeof(a): 52, sizeof(&a): 4 sizeof(ptr): 4, sizeof(*ptr): 52 a.name: 20, a.addr: 12, a.phone: 20 a.: clsu, twon: 1 road: 3 num:36, 4158 ptr->: clsu, twon: 1 road: 3 num:36, 4158

More Related