C 結構體小結


     看了三天結構體,是時候總結一下了。

  關於結構體的聲明:

  

struct Student
{
    char name[20];
    char sex;
    int age;
    char addr[40];
};
/*然后定義一個Student 類型的 student變量*/
struct Student student;

  也許是我受了Java影響,我一度寫成這樣:

struct man
{
    int age = 30;
    int score = 80;
};

int main()
{
    man man1  = {20,70};

}
    

     結果是鐵定編譯通過不了的。因為這是我自創的聲明帶默認值的結構體,編譯器沒見過。結構體成員變量在聲明中是不能賦值的。

  正確的寫法是:

struct Man
{
    int age; //這樣就好了
    int score;
};

int main()
{
   struct Man man1 = {30,80};
}

    定義結構體的時候每次都要寫struct 顯然是煩瑣了,精煉的C語言用來typedef來方便定義使用:

typedef struct Man
{
    int age;
    int score;
}man;

int main()
{
    man man1 = {20,80};
    man man2 = {30,70};
    man man3 = {40,99};
    printf("%d\n",man1.age);
    printf("%d\n",man3.score);
}

  這樣一來大家想召喚多少個“男人”都沒有問題。另外有一個極端一點的問題,聲明結構體名和定義結構體變量名能不能一樣?我們可以試試看:

typedef struct man
{
    int age;
    int score;
}man;  //還叫man,有意見么?

int main()
{
    man man = {40,50};//還叫man,有問題么?
    printf("%d\t%d\n",man.age,man.score);
}

    編譯運行都是沒有問題的。不信自己去試試看。

   然后我們來討論重點吧:

struct Student
{
    char name[20];
    char sex;
    int age;
    char addr[40];
};
/*然后定義一個Student 類型的 student變量*/
struct Student student;

     給定義的結構中name和age賦值, 可以用下面語句:

     strcpy(student->name, "jack");

     student->age=21;

     student->name就是(*student).name的縮寫形式。

    需要指出的是結構指針是指向結構的一個指針, 是結構中第一個成員的首地址, 因此在使用之前應該對結構指針初始化, 即分配整個結構長度的字節空間, 這可用下面函數完成, 仍以上例來說明如下:

     student=(struct string*)malloc(size of (struct string));

    size of (struct string)自動求取string結構的字節長度, malloc() 函數定義了一個大小為結構長度的內存區域, 然后將其詐地址作為結構指針返回。  

    注意:

    結構變量名不是指向該結構的地址, 這與數組名的含義不同,  因此若需要求結構中第一個成員的首地址應該是&[結構變量名]。

 

聯合體

聯合體的結構定義和結構體大體相似。

當一個聯合被說明時, 編譯程序自動地產生一個變量, 其長度為聯合中最大的變量長度。

聯合既可以出現在結構內, 它的成員也可以是結構。

    例如:

     

struct{
          int age;
          char *addr;
          union{
               int i;
               char *ch;
          }x;
     }y[10];  

    若要訪問結構變量y[1]中聯合x的成員i, 可以寫成:

      y[1].x.i;

    若要訪問結構變量y[2]中聯合x的字符串指針ch的第一個字符可寫成:

      *y[2].x.ch;

若寫成"y[2].x.*ch;"是錯誤的。值得指出的是此時的*y[2].x.ch是一個沒有分配內存地址的野指針,直接賦值給它在運行時會崩潰。

 

    結構和聯合都是由多個不同的數據類型成員組成, 但在任何同一時刻, 聯合中只存放了一個被選中的成員, 而結構的所有成員都存在。

    對於聯合的不同成員賦值, 將會對其它成員重寫,  原來成員的值就不存在了, 而對於結構的不同成員賦值是互不影響的。

    下面舉一個例了來加對深聯合的理解。

    

 int main()
     {
          union{                   /*定義一個聯合*/
               int i;
              struct{             /*在聯合中定義一個結構*/
                    char first;
                    char second;
               }half;
          }number;
          number.i=0x4241;         /*聯合成員賦值*/
          printf("%c%c\n", number.half.first, mumber.half.second);
          number.half.first='a';   /*聯合中結構成員賦值*/
          number.half.second='b';
          printf("%x\n", number.i);
     }

 

    輸出結果為:

     AB

     6261

 從上例結果可以看出: 當給i賦值后, 其低八位也就是first和second的值; 當給first和second賦字符后, 這兩個字符的ASCII碼也將作為i 的低八位。

 

用結構體寫一個單鏈表的雛形

#include <stdio.h>
struct node 

{

          struct node *link;
          int value;

};

void main()

{
          struct node node1, node2, node3;
          struct node *head;  //定義鏈表頭指針
          node1.value = 5;       //定義各個節點的內部屬性值
          node2.value = 10;
          node3.value = 15;
          head = &node1;                 //頭指針指向第一個節點的地址

          node1.link = &node2;//第一個節點的指針指向第二個節點的地址
         node2.link = &node3;//第二個節點的指針鏈接到第三個節點的地址
          node3.link = NULL;  //第三個節點的地址為空

          /*打印輸出*/

          struct node *p;
          p = head;
          while(p != NULL)
          {
                   printf("%d\n", p->value);
                   p = p->link;//移動指針到下一個節點

          }       
}

之所以說它是一個單鏈表的雛形,因為他是在是太不完整了,但是至少他已經有單鏈表的影子了。我將慢慢完善改進它。

總結給自己看的,所以整理了我認為重要的部分。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM