【C語言】結構體

一、概念

1. 結構體是由基本數據類型構成的,並由一個標識符來命名的各種變量的組合。結構體中可以使用不同的數據類型。

2. 在實際應用中,我們通常需要由不同類型的數據來構成一個整體,比如學生這個整體可以由姓名、年齡、身高等數據構成,這些數據都具有不同的類型,姓名可以是字符串類型,年齡可以是整型,身高可以是浮點型。

二、結構體的定義

1. 定義形式

   結構體內部的元素,也就是組成部分,我們一般稱作“成員”

   結構體定義形式一般是:

struct 結構體名{
    
    類型名1 成員名1;
    
    類型名2 成員名2;
    
    ……
    
    類型名n 成員名n;   
    
};
如我們定義一個Person
struct Person {
    char *name;
    int age; 
    char *sex;
};
2. 定義結構體變量

 前面只是定義了名字爲Student的結構體類型,並非定義了一個結構體變量,就像int一樣,只是一種類型。

 結構體定義有多種樣式:

 1> 先定義結構體類型,在定義變量

struct Student {
    char *name;
    int age;
};

struct Student stu;
 2> 定義結構體的同時定義變量
struct Student {
    char *name;
    int age;
} stu;
 3> 直接定義結構體類型變量,省略類型名
struct {
    char *name;
    int age;
}stu;
三、注意事項

1. 不允許對結構體本身遞歸定義

 struct Student {
    int age;
    struct Student stu;   // 這裏定義是錯誤的
 };
2. 結構體內可以包含別的結構體
struct Date {
    int year;
    int month;
    int day;
};

struct Student {
    char *name;
    struct Date birthday;
};
3. 定義結構體類型,只是說明了該類型的組成情況,並沒有給它分配存儲空間,就像系統不爲int類型本身分配空間一樣。只有當定義屬於結構體類型的變量時,系統纔會分配存儲空間給該變量
struct Student {
    char *name;
    int age;
};

struct Student stu;   // 這裏才分配存儲空間
4. 結構體變量佔用的內存空間是其成員所佔內存之和,而且各成員在內存中按定義的順序依次排列
struct Student {
    char *name; // 姓名
    int age; // 年齡
    float height; // 身高
};
四、結構體的初始化

  將各成員的初值,按順序地放在一對大括號{}中,並用逗號分隔,一一對應賦值。
  比如初始化Student結構體變量stu

struct Student {
    char *name;
    int age;
};

struct Student stu = {"aa", 27};
只能在定義變量的同時進行初始化賦值,初始化賦值和變量的定義不能分開,下面的做法是錯誤的:
struct Student stu;
stu = {"aa", 27};
五、結構體的使用

1. 一般對結構體變量的操作是以成員爲單位進行的,引用的一般形式爲:結構體變量名.成員名

struct Student {
    char *name;
    int age;
};

struct Student stu;

// 訪問stu的age成員
stu.age = 27;
2. 如果某個成員也是結構體變量,可以連續使用成員運算符"."訪問最低一級成員
struct Date {
     int year;
     int month;
     int day;
};

struct Student {
    char *name;
    struct Date birthday;
};

struct Student stu;

stu.birthday.year = 1986;
stu.birthday.month = 9;
stu.birthday.day = 10;
六、結構體數組

1. 定義形式與結構體變量一樣,也有三種形式

struct Student {
    char *name;
    int age;
};
struct Student stu[5]; //定義1
2. 初始化
struct {
    char *name;
    int age;
} stu[2] = { {"MJ", 27}, {"JJ", 30} };
七、結構體作爲函數參數

 將結構體變量作爲函數參數進行傳遞時,其實傳遞的是全部成員的值,也就是將實參中成員的值一一賦值給對應的形參成員。因此,形參的改變不會影響到實參

#include <stdio.h>

// 定義一個結構體
struct Student {
    int age;
};

void test(struct Student stu) {
    printf("修改前的形參:%d \n", stu.age);
    // 修改實參中的age
    stu.age = 10;
    
    printf("修改後的形參:%d \n", stu.age);
}

int main(int argc, const char * argv[]) {
    
    struct Student stu = {30};
    printf("修改前的實參:%d \n", stu.age);  // 30
    
    // 調用test函數
    test(stu);   // 30  10
    
    
    printf("修改後的實參:%d \n", stu.age); // 30
    return 0;
}

八、指向結構體的指針* 每個結構體變量都有自己的存儲空間和地址,因此指針也可以指向結構體變量* 結構體指針變量的定義形式:
        struct 結構體名稱 *指針變量名* 有了指向結構體的指針,那麼就有3種訪問結構體成員的方式  (等效)
結構體變量名.成員名
(*指針變量名).成員名
指針變量名->成員名
#include <stdio.h>

int main(int argc, const char * argv[]) {
    // 定義一個結構體類型
    struct Student {
        char *name;
        int age;
    };
    
    // 定義一個結構體變量
    struct Student stu = {"MJ", 27};
    
    // 定義一個指向結構體的指針變量
    struct Student *p;
    
    // 指向結構體變量stu
    p = &stu;

    /*
     這時候可以用3種方式訪問結構體的成員
     */
    // 方式1:結構體變量名.成員名
    printf("name=%s, age = %d \n", stu.name, stu.age);
    
    // 方式2:(*指針變量名).成員名
    printf("name=%s, age = %d \n", (*p).name, (*p).age);
    
    // 方式3:指針變量名->成員名
    printf("name=%s, age = %d \n", p->name, p->age);
    
    return 0;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章