1. 程式人生 > >1-C語言之結構體、共用體、列舉

1-C語言之結構體、共用體、列舉

一、關鍵字說明

        C語言有32個關鍵字,C語言通過關鍵字的使用使編譯器進行相關的操作

         結構體對應關鍵字struct

         共用體(聯合體)對應的關鍵字是union

         列舉型別對應的關鍵字是enum

二、結構體、共用體(聯合體)、列舉定義

        結構體的定義:一種或多種基本型別或構造型別的資料的集合(構造型別)。

        共用體(聯合體)的定義:所謂的共用體(聯合體)就是其中的成員共用一段記憶體,記憶體的大小由最大的那個成員的大小確定。

        列舉型別:C語言等計算機程式語言中是一種構造資料型別,它用於宣告一組命名的常數,當一個變數有幾種可能的取值時,可以將它定義為列舉型別。

三、結構體、共用體與記憶體分配的關係

         結構體:記憶體對齊——最大以4位元組對齊(32位機)

        共用體:

四、結構體的使用

         step1:結構體的定義

                 (1)先定義結構體型別,再去定義結構體變數

                 (2)struct  結構體型別名{

                              成員列表

                  };

                (3)構造的資料型別是 struct 結構體型別名

               (4)例子

                    struct stu{

                              int num;

                              char name[20];

                              char sex;

                     };

         step2:結構體取成員操作

                  (1)採用.取結構體成員

                  (2)採用->取結構體成員

                   定義結構體指標,用結構體指標->成員變數進行取值操作

                  (3)基址 + 偏移 = 取成員

         step3:結構體的初始化和使用

                  (1)直接定義時並初始化

              

              (2)採用bzero和memset對結構體進行初始化,初始化後直接進行賦值操作

       

        step4:結構體陣列

         (1)結構體陣列的定義:結構體陣列是個陣列,由若干個相同型別的結構體變數構成的集合

         (2)結構體陣列(類似int a[10])的定義方法:

          .NOTE:結構體陣列從兩方面來理解

                        (1)結構體和基本資料型別,原則上都是資料型別,一個是構造資料型別,一個是基本資料型別

                        (2)陣列方面:基本資料型別int a[10],  構造資料型別struct stu student[10]

                          struct stu{

                                         int num;

                                         char name[20];

                                          char sex;

                           };

                        struct stu student[10];

                        這個陣列有10個元素分別是student[0] 、student[1]、student[2]..........student[9]

          (3)陣列元素的使用

                1)student0].num =101;//用101給student陣列的第0個結構體變數的num賦值

                2)使用字串操作函式:strcpy(student[1].name,"lucy");

         step5:結構體指標

        (1)結構體指標:即結構體的地址

        (2)定義一個變數來存放這個地址,那這個變數就是結構體指標變數。

        (3)結構體指標變數的定義方法:

       .NOTE:結構體指標從兩方面來理解

                        (1)結構體和基本資料型別,原則上都是資料型別,一個是構造資料型別,一個是基本資料型別

                        (2)指標變數方面:基本資料型別int *a,  構造資料型別struct stu *ps

         (4)struct stu{

                   int num;

                  char name[20];

            };

           struct stu * p;//定義了一個struct stu *型別的指標變數,變數名是p,p佔4個位元組,用來儲存結構體變數的地址編號

     (5)使用: struct stu boy;

                      struct stu *p; 

                      p=&boy;

         訪問結構體變數的成員方法:

           (1)boy.num=101;//可以,通過結構體變數名.成員名

           (2)(*p).num=101;//可以,*p相當於p指向的變數boy

           (3)p->num=101;//可以,指標->成員名 

通過結構體指標來引用指標指向的結構體的成員,前提是指標必須先指向一個結構體變數。

        step6:結構體記憶體對齊機制——記憶體對齊,提高定址效率

                     用空間來換時間,提高cpu讀取資料的效率

規則1:結構體分配記憶體時哪個基本型別的成員佔位元組數多,就以它的大小為單位開闢記憶體,

在gcc中出現了double型別的,例外

1:成員中只有char型資料 ,以1位元組為單位開闢記憶體。

2:成員中出現了short int 沒有更大位元組數的基本型別資料以2位元組為單位開闢記憶體

3、出現了int float 沒有更大位元組的基本型別資料的時候以4位元組為單位開闢記憶體。

4、出現了double型別的資料

情況1:

         在vc裡,以8位元組為單位開闢記憶體。

情況2:

        在gcc裡,以4位元組為單位開闢記憶體。

無論是那種環境,double型變數,佔8位元組。

注意:

            如果在結構體中出現了陣列,陣列可以看成多個變數的集合。

            如果出現指標的話,沒有佔位元組數更大的型別的,以4位元組為單位開闢記憶體。

            在記憶體中儲存結構體成員的時候,按定義的結構體成員的順序儲存。

例1:struct stu{

             char sex;

             int age;

         }lucy;

        lucy的大小是4的倍數。

規則2:位元組對齊

1:char 1位元組對齊 ,即存放char型的變數,記憶體單元的編號是1的倍數即可。

2:short int 2位元組對齊 ,即存放short int 型的變數,起始記憶體單元的編號是2的倍數即可。

3:int 4位元組對齊 ,即存放int 型的變數,起始記憶體單元的編號是4的倍數即可

4:long int 在32位平臺下,4位元組對齊 ,即存放long int 型的變數,起始記憶體單元的編號是4的倍數即可

5:float 4位元組對齊 ,即存放float 型的變數,起始記憶體單元的編號是4的倍數即可

6:double

1.vc環境下

         8位元組對齊,即存放double型變數的起始地址,必須是8的倍數,double變數佔8位元組

2.gcc環境下

         4位元組對齊,即存放double型變數的起始地址,必須是4的倍數,double變數佔8位元組。

注意3:當結構體成員中出現數組的時候,可以看成多個變數。

注意4:開闢記憶體的時候,從上向下依次按成員在結構體中的位置順序開闢空間

例1:

struct stu{

              char a;

              short b;

              int c;

         }temp;

五、共用體(聯合體)的使用

         step1:共用體的定義

             (1)幾種不同型別的變數存到同一段記憶體單元中,幾個變數所使用空間相互重疊

             (2)這種幾個不同的變數共同佔用一段記憶體的結構,在C語言中,被稱作“共用體”型別結構

             (3)共用體所有成員佔有同一段地址空間

         step2:共用體的大小

            (1)共用體的大小是其佔記憶體長度最大的成員的大小

                 typedef union data{

                          short int i;

                          char ch;

                          float f;

                 }DATA;

                 DATA temp2;

                 共用體temp2佔4個位元組,即i、ch、f共用4個位元組

         step3:共用體與大小端序

         step6:共用體的本質

                       根據union固定首地址union按最大需求開闢一段記憶體空間兩個特徵,可以發現,所有表面的定義都是虛的,所謂聯合體union,就是在記憶體給你劃了一個足夠用的空間,至於你怎麼玩~它不管~!(何止是union和struct,C不就是玩地址麼,所以使用C靈活,也容易犯錯)

  給你首地址 + 記憶體空間,剩下的自己操作

六、列舉型別的應用

         step1:列舉型別的定義

                       在C語言等計算機程式語言中是一種構造資料型別,它用於宣告一組命名的常數,當一個變數有幾種可能的取值時,可以將它定義為列舉型別

         step2:列舉型別的特徵

         (1) 列舉型是一個集合,集合中的元素(列舉成員)是一些命名的整型常量,元素之間用逗號,隔開。

         (2) DAY是一個識別符號,可以看成這個集合的名字,是一個可選項,即是可有可無的項。

         (3) 第一個列舉成員的預設值為整型的0,後續列舉成員的值在前一個成員上加1。

         (4) 可以人為設定列舉成員的值,從而自定義某個範圍內的整數。

         (5) 列舉型是預處理指令#define的替代。

         (6) 型別定義以分號;結束。

         step3:列舉宣告變數——列舉構造資料型別,與基本資料型別一致,都是資料型別

         (1)列舉型別的定義和變數的宣告分開

      

       (2)型別定義與變數宣告同時進行

        (3)用typedef關鍵字型別重定義

        .NOTE:同一個程式中不能定義同名的列舉型別,不同的列舉型別中也不能存在同名的命名常量

         step4:使用列舉型別的變數

        (1)先宣告變數,再對變數賦值

        (2)宣告變數的同時賦初值

        (3)定義型別的同時宣告變數,然後對變數賦值

     

         (4)定義型別的同時宣告變數,然後對變數賦值

step5:enum與sizeof的千絲萬縷

        列舉就是在其相應作用域內的一個識別符號而已,編譯器根本不知道什麼是列舉這個東西,列舉對於編譯器來說就是int型別的值而已,只不過是個常量int,列舉的一切行為表現都與一個普通的int值沒有區別,所以sizeof的值為4(32位機)。