第9章 結構、聯合、列舉與定義型態



   結構簡介
   其它自訂資料型態
   上機實習課程
9-1 結構簡介
結構宣告與存取(1)

   結構的架構必須具有結構名稱與結構項目,而
    且必須使用關鍵字struct來建立,一個結構的
    基本宣告方式如下所示:

    struct 結構名稱
    {
       資料型態 結構成員1;
       資料型態 結構成員2;
       ......
    };

                                 2
9-1 結構簡介




 在結構定義中可以使用基本的變數、陣列、指標,
  甚至是其它結構成員等。
 注意在定義之後的分號不可省略,這是經常忽略
  而使得程式出錯的地方,以下為一個結構定義的
  實際例子,結構中定義了學生的姓名與成績:

    struct student
    {
       char name[10];
       int score;
       int ID;
    };                             3
9-1 結構簡介




 在定義了結構之後,我們可以直接使用它來建
  立結構物件,結構定義本身就像是個建構物件
  的藍圖或模子。
 而結構物件則是根據這個藍圖製造出來的成品
  或模型,每個所建立的結構物件都擁有相同的
  結構成員,一個宣告建立結構物件的例子如下
  所示:
    struct student s1, s2;


                                        4
9-1 結構簡介




 在建立結構物件之後,我們可以使用英文句號.
  來存取結構成員,這個句號通常稱之為「點運
  算子」(dot operator)。
 只要在結構變數後加上成員運算子"."與結構成
  員名稱,就可以直接存取該筆資料:

    結構變數.項目成員名稱;




                              5
結構宣告與存取(2)          9-1 結構簡介



   程式範例:結構宣告與存取的基本應用範例:
    CH09_01.c




                               6
9-1 結構簡介




           7
9-1 結構簡介


   執行結果




   程式解說

    第6~11行中定義並宣告student結構的s1,s2變數。
    請注意在第14行中不可以直接將字串值直接指定給
    字元陣列,必須要使用strcpy()函數。
    第19行使用gets()函數輸入s2.name初始值。
    第24~25行中計算兩個結構變數的總分及平均。             8
結構宣告與存取(3)          9-1 結構簡介



   程式範例:不定義結構名稱與同時指定初始值
    的基本應用範例:CH09_02.c




                               9
9-1 結構簡介




   執行結果




   程式解說

    第6~11行中不定義新的結構型態,卻宣告結構變
    數,並以大括號括住來設定結構變數成員。            10
9-1 結構簡介
巢狀結構(1)
   基本結構如下:

    struct 結構名稱1
    {
       ……
    };
    struct 結構名稱2
    {
    ……
       struct 結構名稱1 變數名稱;
       ……

                                       11
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};    12
9-1 結構簡介
巢狀結構(2)
   程式範例:巢狀結構的基本應用範例:
    CH09_03.c




                               13
9-1 結構簡介




   執行結果


                      14
9-1 結構簡介




   程式解說

    第6~10行定義結構name,第12~17行定義則巢狀
    結構 member。
    第17行宣告了member型態的結構變數m1,並設定
    初始值。
    第21行輸出巢狀結構中的成員。




                                     15
9-1 結構簡介
結構陣列(1)

   下面這個程式碼片段將建立具有五個元素的結
    構陣列:

    struct student
    {
       char name[10];
       int math;
       int english;
    };

    struct student class1[3];
                                           16
9-1 結構簡介




   如果同時要記錄多筆相同結構資料,還是得宣
    告一個結構陣列型態。宣告方式如下:

    struct 結構型態名稱 結構陣列名稱[元素個素];

   至於要存取的成員,在陣列後方加上"[索引值]"
    存取該元素即可,例如:

    結構陣列名稱[索引值].陣列成員名稱


                                        17
9-1 結構簡介
結構陣列(2)
   程式範例:結構陣列的基本應用範例:CH09_04.c




                                  18
9-1 結構簡介




           19
9-1 結構簡介



   執行結果




   程式解說
    第6~11行中定義studen結構,其中包括字串name、整
    數math與整數english三種資料成員。
    第13~14行定義並設定3個元素的結構陣列初始值。
    第21行計算數學總分及第22行計算英文總分。
    第27行計算3個學生的兩科平均成績。                20
9-1 結構簡介




   在結構陣列中的資料成員也可以宣告為陣列型
    態,如果各位在結構陣列中要宣告陣列成員,
    也是直接在陣列前面加上資料型態即可,如下
    所示:

    struct 結構名稱
    {
       ……
       資料型態 陣列名稱[元素個數];
    };

    struct 結構名稱 結構陣列名稱[元素個數;              21
結構陣列(3)             9-1 結構簡介



   程式範例:結構陣列的陣列資料成員的宣告與
    存取範例:CH09_05.c




                               22
9-1 結構簡介




           23
9-1 結構簡介



   執行結果




   程式解說
第6~11行,定義club結構 ,結構中有name陣列資料成員。
定義並設定結構陣列初始值。
第26行輸出每一個club的陣列成員姓名字串。
                                    24
9-1 結構簡介
結構與記憶體位址(1)
   定義與宣告:
    struct member
    {
       char name[20];
       int age;
    };
    struct member m1;

   在結構變數m1中,其成員name與age在記憶
    體中將會如下分佈:


                                   25
9-1 結構簡介
結構與記憶體位址(2)
   程式範例:指標變數與結構成員記憶體位址宣
    告與存取範例:CH09_06.c




                               26
9-1 結構簡介




   執行結果



                      27
9-1 結構簡介




   程式解說

    第6~11行定義member結構。
    第18行中,我們直接將m1.name指定給ptr1,這
    是因為陣列名稱本身就代表記憶體位址。
    第19行&運算子表示取得成員s1.age的記憶體位
    址,再指定給ptr2。




                                      28
結構與記憶體位址(3)         9-1 結構簡介



   程式範例:結構陣列或變數的記憶體大小求取
    範例:CH09_07.c




                               29
9-1 結構簡介


   執行結果




   程式解說

第12行整個結構陣列所佔有的記憶體容量是120個位元
組,而一個陣列元素所佔的空間是24位元,因此結構
陣列所佔空間為24*5=120。
第14行的name資料成員記憶體是20位元,第15行age
資料成員記憶體是4位元。                      30
9-1 結構簡介
結構指標(1)

   宣告方式如下:

    struct 結構名稱 *結構指標名稱;

   宣告好結構型態及結構指標之後,才能間接存
    取其指定結構變數的成員。如下所示:

    結構指標名稱 = &結構變數名稱;




                                      31
9-1 結構簡介




   例如我們可以在程式中定義如下的結構指標宣告:

    struct member
       {
           char name[20];
           int age;
       } m1;
    struct member *ptr; /* 宣告結構指標 */
    ptr=&m1;


                                                  32
結構指標(2)             9-1 結構簡介


   程式範例:結構指標的宣告與存取範例:
    CH09_08.c




                               33
9-1 結構簡介




           34
9-1 結構簡介



   執行結果




   程式解說

    第13行宣告結構指標ptr,並在第25行初始化指標,
    將ptr指向m1結構變數。
    第27、29行是利用第一種結構指標存取方式。
    第31行初始化指標,將ptr指向m2結構變數。
    第33、35行是利用第二種結構指標存取方式。          35
9-1 結構簡介
結構指標(3)
   程式範例:結構陣列與指標常數存取範例:
    CH09_09.c




                               36
9-1 結構簡介




           37
9-1 結構簡介



   執行結果




   程式解說

    第14~17行定義並設定結構陣列初始值,第20、
    25行以指標常數方式輸出結構陣列的資料成員。

                                   38
9-1 結構簡介
結構與函數傳值呼叫(1)

   結構傳值呼叫的函數宣告如下:

    函數型別 函數名稱(struct 結構名稱 結構變數);
    {
      函數主體;
    }

   呼叫函數的語法如下:

    函數名稱(結構變數);


                                       39
結構與函數傳值呼叫(2)        9-1 結構簡介



   程式範例:結構與傳值呼叫的函數範例:
    CH09_10.c




                               40
9-1 結構簡介




           41
9-1 結構簡介


   執行結果




   程式解說
第4~9行定義結構 ,並使這個club結構為全域性的結構型
態。
第11行結構變數傳值呼叫函數原型宣告。
第17行定義並設定結構陣列初始值。第20行呼叫函數。
第26~33定義show()函數主體,並於28、29行輸出s的資
料成員。                                42
結構與函數傳值呼叫(3)             9-1 結構簡介



   程式範例:結構與傳值呼叫calculate()函數應
    用範例:CH09_11.c




                                    43
9-1 結構簡介




           44
9-1 結構簡介


   執行結果




   程式解說
    第12行結構變數傳值呼叫函數calculate()的原型宣告,第17行
    宣告stud結構變數,並設定結構初始值。
    第19行以傳值呼叫傳遞stud變數。
    第21行輸出stud變數的原來設定值,雖然在calculate()函數中
    已改變Chi資料成員的值。
    第31行Chi的值乘以1.3,因此在第35行輸出時的值是
    60*1.3=78,但不會改變main()函數中的原值。           45
9-1 結構簡介
結構與函數傳址呼叫(1)

   結構傳址呼叫的函數宣告如下:

    函數型別 函數名稱(struct 結構名稱 *結構變數);
    {
      函數主體;
    }

   呼叫函數的語法如下:

    函數名稱(&結構變數);

                                        46
結構與函數傳址呼叫(2)             9-1 結構簡介



   程式範例:結構與傳址呼叫calculate()函數的
    應用範例:CH09_12.c




                                    47
9-1 結構簡介




           48
9-1 結構簡介


   執行結果




   程式解說
第12行 結構變數傳址呼叫函數的原型宣告。
第19行呼叫calculate()函數,必須使用「&」運算子。
第30~32行以第二種結構指標方式來存取資料成員,各
位也可以使用第一種方式,如(*s1).Eng=(*s1).Eng*1;。
在第35行輸出此結構變數時,已改變Chi資料成員的值,
當回到main()函數後第21行輸出時,Chi資料成員的值也
同步改變了。                                 49
結構與函數傳址呼叫(3)          9-1 結構簡介



   程式範例:結構與傳址呼叫max()函數的應用
    範例:CH09_13.c




                                 50
9-1 結構簡介




           51
9-1 結構簡介



   執行結果




   程式解說
    第4~9行是定義全域的結構member,第10行為傳址函
    數max()的原型宣告。
    第20行呼叫max()函數,記得使用「&」運算子。
    第36~38行執行交換運算,找出p1或p2哪一位salary資
    料成員高。                               52
結構與函數傳址呼叫(4)          9-1 結構簡介



   程式範例:結構與傳址呼叫max()函數的應用
    範例:CH09_14.c




                                 53
9-1 結構簡介




           54
9-1 結構簡介




   執行結果




                      55
9-1 結構簡介




   程式解說

    第10行以傳址呼叫的函數原型宣告。
    第20行定義並設定結構陣列初始值。
    第22行呼叫並傳遞陣列到函數中。
    第28~44行定義傳遞陣列的傳址呼叫函數。




                                   56
結構與函數傳址呼叫(5)          9-1 結構簡介



   程式範例:結構與傳址呼叫min()函數的應用範
    例:CH09_15.c




                                 57
9-1 結構簡介




           58
9-1 結構簡介



   執行結果




   程式解說
    第10行以傳址呼叫的函數原型宣告。
    第17~19行定義並設定結構陣列初始值。
    第21 c;61呼叫並傳遞陣列到min()函數。
    第32行設定陣列第一筆元素成績為min_score。
    第33~38行以for迴圈找出最小值。              59
9-2 其它自訂資料型態
列舉型態(1)

   宣告語法如下:

    enum 列舉型態名稱
    {
      列舉成員1,
      列舉成員2,
       ……
    }
    enum列舉型態名稱 列舉變數1,列舉變數2…;



                                      60
9-2 其它自訂資料型態




   例如以下宣告:

    enum animal
    {
         tiger,
         monkey,
         dog,
         cat
    }; /* 定義列舉型態 animal */
    enum animal zoo1,zoo2; /* 宣告列舉型態animal的
    變數 zoo1與zoo2 */
                                              61
9-2 其它自訂資料型態
列舉型態(2)

   程式範例:列舉型態的宣告與應用範例:
    CH09_16.c




                                62
9-2 其它自訂資料型態




   執行結果




                          63
9-2 其它自訂資料型態




   程式解說

    第6~10行定義一個列舉型態 animal。
    第12行宣告列舉型態animal的變數 zoo1與zoo2。
    第13、14行分別將zoo1、zoo2的值設定為tiger與dog。
    第16行輸出各個animal列舉成員所代表的整數常數值。




                                         64
列舉型態(3)          9-2 其它自訂資料型態



   程式範例:列舉型態的宣告與更改初始值範例:
    CH09_17.c




                                65
9-2 其它自訂資料型態




   執行結果



   程式解說
第7行中我們重新設定tiger的初始值,第9行中則重新設定dog的
初始值。
第13、14行將zoo1的值設定為tiger及將zoo2的值設定為dog。   66
9-2 其它自訂資料型態
型態定義功能(1)

   宣告語法如下:

    typedef 原資料型態 新定義型態識別字

   例如:

    typedef int integer;
    int height=50;
    integer age=120;
    type char* strinng;
    string s1="我是張大大"
                                          67
型態定義功能(2)           9-2 其它自訂資料型態



   程式範例:型態定義(typedef)的使用與宣告範
    例:CH09_18.c




                                   68
9-2 其它自訂資料型態




   執行結果




   程式解說

    第4行把int定義成INTEGER,而第5行則把char*定
    義成STRING。
    第9~10行分別宣告score是 INTEGER型態與宣告s1
    是STRING型態。                          69
9-2 其它自訂資料型態




   通常在定義結構之後,我們會使用typedef定義
    結構的資料型態名稱別名,程式碼宣告就不必
    每次加上struct保留字了,以方便宣告結構變
    數,例如:

struct student
{
   char name[10];
   int score;
};
typedef struct student sdn; /* 定義資料型態名稱為sdn */
snd s1, s2; /* 使用snd名稱宣告結構物件s1與s2 */             70
型態定義功能(3)        9-2 其它自訂資料型態



   程式範例:型態定義與結構型態的使用與宣告
    範例:CH09_19.c




                                71
9-2 其它自訂資料型態




               72
9-2 其它自訂資料型態




               73
9-2 其它自訂資料型態



   執行結果




                          74
9-2 其它自訂資料型態




   程式解說

    第9行定義資料型態名稱為sdn。
    第15行~19行宣告snd型態的s陣列,並設定初始值。
    第29~30行由於陣列是傳址方式,所以排序後的結果
    會直接影響s陣列,我們只要直接於主函式中再次顯示
    s的內容,即可顯示排序後的結果。
    第36~49行以氣泡排序法來進行對fs陣列的排序,使用
    的觀念是兩個結構物件變數若相同,則可以直接使用
    指定運算子進行成員資料的複製。

                                    75
聯合型態(1)                                9-2 其它自訂資料型態


   聯合型態的宣告方式如下:
      union 聯合名稱
      {
        資料型態1 資料成員1;
        資料型態2 資料成員2;
        資料型態3 資料成員3;
            ……
      }聯合變數;

   例如以下是聯合型態的宣告:
    union student
    {
     char name[10];/* 佔10bytes 空間 */
     int score;/* 佔 4bytes 空間 */
    };                                                76
聯合型態(2)          9-2 其它自訂資料型態



   程式範例:聯合與結構型態的使用與宣告比較
    範例:CH09_20.c




                                77
9-2 其它自訂資料型態




   執行結果




                          78
9-2 其它自訂資料型態




   程式解說

    第4~8行宣告結構型態student1,第10~14行宣告聯合型
    態student。
    第18~19行s1為結構變數與s為聯合變數。
    第21行輸出結構變數與聯合變數所佔位元組。

   至於聯合型態的存取方式是在聯合變數後加上
    小數點「.」再加上資料成員即可:

    聯合物件.資料成員;
                                       79
聯合型態(3)          9-2 其它自訂資料型態



   程式範例:聯合型態的宣告與存取範例:
    CH09_21.c




                                80
9-2 其它自訂資料型態




   執行結果



   程式解說
           第14行宣告s為聯合變數。
           第15行設定s.name初始值。
           第16行存取s.name的值。
           第17行設定s.score初始值。
           第18行存取s.score的值。            81
9-3 上機實習課程
上機實習課程(1)

   上機實習範例:CH09_22.c
    – 假設現在有以下結構型態:




    – 請設計一程式來輸出結構變數desk一共佔了多
     少位元組。
                                    82
9-3 上機實習課程




             83
9-3 上機實習課程




   執行結果




                        84
9-3 上機實習課程
上機實習課程(2)

   上機實習範例:CH09_23.c
    – 由於陣列名稱可以利用指標常數來存取,各位
     也可以指標常數方式來表示結構陣列。例如以
     下student型態的結構陣列class1:

struct student
  {
      char name[20];
      int math;
      int english;
   };
struct student class1[5]=
 {{"章成方",87,79},{"王克擎",81,100},{"林函樓",78,90},{"吳黛玲
",99,85},{"陳昭輝",90,65}};                             85
9-3 上機實習課程




             86
9-3 上機實習課程




             87
9-3 上機實習課程




   執行結果




                        88
9-3 上機實習課程
上機實習課程(3)

   上機實習範例:CH09_24.c
    – 試設計一程式,定義一巢狀結構product,其資
      料成員包含price(價格)與規格(scale),而規格
      (scale)是屬於size結構的變數,由長(length)、
      寬(width)與高(height)三個成員所組成。
    – 在此程式中宣告及設定一個product型態變數
      desk,並輸出其所有成員資料。




                                         89
9-3 上機實習課程




             90
9-3 上機實習課程




   執行結果




                        91
9-3 上機實習課程
上機實習課程(4)

   上機實習範例:CH09_25.c
    – 延續上題,請設計一結構傳值呼叫函數,可傳
     遞兩結構變數,並可用資料成員(長*寬*高)來比
     較這兩變數的體積大小,及傳回與輸出體積較
     大者的所有資料成員。




                                    92
9-3 上機實習課程




             93
9-3 上機實習課程




   執行結果




                        94
9-3 上機實習課程
上機實習課程(5)

   上機實習範例:CH09_26.c
    – 延續上題,請設計一結構傳址呼叫函數,可傳
      遞一結構陣列變數,如陣列元素的價格(price)
      資料成員大於12000,則可享有九折優惠,並
      更改price成員的值。
    – 最後傳回打完折後的陣列與輸出此陣列所有元
      素的資料成員。




                                    95
9-3 上機實習課程




             96
9-3 上機實習課程




             97
9-3 上機實習課程



   執行結果




                        98
9-3 上機實習課程
上機實習課程(6)

   上機實習範例:CH09_27.c
    – 我們可以使用結構自訂資料型態,也能使用結
      構來宣告指標陣列,陣列中的每個元素,所存
      放的都是指標。
    – 以下程式範例中將以結構指標陣列s2的每個元
      素都指向結構陣列s1的每個元素,並利用s2陣
      列來進行氣泡法排序及由分數大小輸出所有陣
      列元素的資料成員。



                                    99
9-3 上機實習課程




             100
9-3 上機實習課程




             101
9-3 上機實習課程




   執行結果




                        102
上機實習課程(7)                 9-3 上機實習課程



   上機實習範例:CH09_28.c
    – 以下程式範例,將使用練習malloc()與free()這
     兩個函式,首先以malloc()動態配置的方式,配
     置給結構變數一個記憶體空間,並於程式結束
     前,使用free() 釋放所配置的資源。




                                       103
9-3 上機實習課程




             104
9-3 上機實習課程
上機實習課程(8)

   執行結果




   上機實習範例:CH09_29.c
    – 在動態配置記憶體空間時,最常使用的就是「串
      列」(link)結構。
    – 對於一個基本的串列結構,我們必須使用一個資
      料欄與一個指標ptr記錄最後一個元素的位置。        105
9-3 上機實習課程




   假設我們現在要新增一個元素至串列的尾端,
    在程式上必須設計四個步驟:

    1.使用malloc()配置記憶體空間給新元素新節點使用。
    2. 將原串列尾端的指標欄(next)指向新元素所在的記
    憶體位置。
    3.將ptr指標指向新節點的記憶體位置,表示這是新的
    串列尾端。
    4. 由於新節點目前為串列最後一個元素,所以將它的
    指標欄(next)指向NULL。

                                      106
9-3 上機實習課程




             107
9-3 上機實習課程




             108
9-3 上機實習課程




             109
9-3 上機實習課程




   執行結果




                        110
上機實習課程(9)              9-3 上機實習課程



   上機實習範例:CH09_30.c
    – 以下程式範例是要說明如果於結構型態內宣告
      指標成員,如何存取此指標變數的方法。
    – 當結構成員宣告為指標變數,在實體結構物件
      中則以小數點「.」存取指標變數




                                    111
9-3 上機實習課程




   執行結果

                        112
上機實習課程(10)             9-3 上機實習課程



   上機實習範例:CH09_31.c
    – 延續上題,以下程式範例是說明如果於結構型
     態內宣告指標成員,而且當必須結構指標來存
     取資料成員時時,則必須以(->)運算子存取指標
     成員及其他資料成員。




                                    113
9-3 上機實習課程




             114
9-3 上機實習課程



   執行結果




   上機實習範例:CH09_32.c
    – 在程式中若以數值表示顏色,意義上較不清楚,
      這時可以使用「列舉常數」(enumeration
      constants)來自訂列舉型態。
    – 若要設定列舉的初值,則直接於宣告的同時指
      定其值就可以了,如下所示:
    enum colors { RED = 1, ORANGE, YELLOW,
                                                115
    GREEN, BLUE, INDIGO, PURPLE };
9-3 上機實習課程




   執行結果

                        116
上機實習課程(11)             9-3 上機實習課程



   上機實習範例:CH09_33.c
    – 以下程式範例是將結構指標指向陣列,並利用
     結構指標的加法運算存取陣列中所有元素的資
     料成員。




                                    117
9-3 上機實習課程




   執行結果




                        118
9-3 上機實習課程
上機實習課程(12)
   上機實習範例:CH09_34.c
    – 以下程式範例中由於要將結構資料當作傳回值,
     因此必須在該函式中先建立結構資料變數,然
     後輸入結構成員的值,並將所輸入的值傳回呼
     叫的敘述句。




                                    119
9-3 上機實習課程




             120
9-3 上機實習課程




   執行結果




                        121

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

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