目錄
一、結構體(struct)
1.1類型定義
1.2 結構體變量定義
1.3 結構體元素初始化
1.4 結構體成員訪問
1.5 結構體的存儲(內存對齊)
1.6 結構體傳參
本文主要記錄了C語言中構造數據類型部分的內容,今天暫時只寫了結構體的內容,關于結構體的定義、變量定義、初始化、訪問、存儲和傳參問題,很好理解,后續共用體(聯合體)和枚舉問題將于明天進行更新。
一、結構體(struct)
結構體是一種自定義的復合數據類型,用于將不同類型的數據組合成一個整體,方便對相關數據進行統一管理和操作。
1.1類型定義
struct 結構體名 {
數據類型1 成員變量1;
數據類型2 成員變量2;
數據類型3 成員變量3;
...
};struct date {
int year;
int mon;
int day;
};struct time {
int hour;
int min;
int sec;
};struct student {
char name[32];
char sex;
int age;
int score;
};
基本格式:使用struct
關鍵字,后跟結構體名,大括號內包含多個成員變量(成員可以是基本數據類型、其他結構體類型等),最后以分號結尾。
- 說明:定義的是結構體類型,并非變量,就像
int
是類型,不是具體變量一樣。
1.2 結構體變量定義
定義:存儲類型 + 結構體類型 + 變量名。
struct student stu1;? //
(定義一個struct student
類型的變量stu1
)
注意:存儲類型可省略,默認是自動存儲類型(auto)。
1.3 結構體元素初始化
- 全部初始化:按成員順序依次賦值。
struct student stu = {"zhangsan", 'm', 18, 90};
- 局部初始化:可指定部分成員賦值,未賦值的成員自動為 0(數值型)、空字符(字符型)等默認值。
?struct student stu = {.name = "zhangsan", // 指定name成員賦值.score = 90 // 指定score成員賦值 };
1.4 結構體成員訪問
- 結構體變量訪問成員:使用
.
運算符,格式為 “結構體變量名 . 成員名” - 結構體指針訪問成員:使用
->
運算符,格式為 “結構體指針名 -> 成員名”
. :結構體變量類型訪問成員變量 .
-> :結構體指針類型訪問成員變量 ->結構體訪問成員變量最終的類型由成員變量的類型決定
1.5 結構體的存儲(內存對齊)
- 結構體成員必須存放在內存地址為自身類型長度整數倍的內存單元中。例如
int
類型成員(占 4 字節)的地址必須是 4 的倍數。 - 結構體的總大小必須為自身最大成員類型長度的整數倍。
-
struct student {char name[32];char sex;int age;int score; };
作用:內存對齊是為了提高 CPU 對內存的訪問效率,硬件層面更易讀取對齊的地址。
1.6 結構體傳參
1.傳值方式:函數參數是結構體變量,實參將整個結構體的內容拷貝給形參,缺點是當結構體較大時,拷貝開銷大。
void fun(struct student tmp);
2.傳地址方式:函數參數是結構體指針,實參將結構體的地址傳遞給形參,僅拷貝 8 字節(64 位系統指針大小),效率更高,且可通過指針修改原結構體內容。
void fun(struct student *ptmp);
建議:優先使用傳地址方式,尤其對于大型結構體;
? ? ? ? ? ?傳地址更好,因為實參將8字節拷貝給形參,避免結構體大空間的拷貝;
二. 共用體(union,聯合體)
共用體與結構體的核心區別是所有成員共享同一塊內存空間,空間大小等于最大成員的大小,適用于 “同一空間存儲不同類型數據” 的場景(如節省內存、判斷內存大小端)。
(1)定義與特性
- 定義格式:
union 共用體名 {成員列表};
union Data {int i; // 占4字節float f; // 占4字節char c; // 占1字節 }; // 總大小為4字節(最大成員int和float均為4字節)
- 特性:任一時刻只有一個成員有效,修改一個成員會覆蓋其他成員的值。
(2)應用:判斷內存大小端
內存大小端是指多字節數據在內存中的存儲順序:
- 小端存儲:低地址存儲數據的低字節(如 0x12345678,低地址存 0x78);
- 大端存儲:低地址存儲數據的高字節(如 0x12345678,低地址存 0x12)。
利用共用體判斷:
#include <stdio.h>
union CheckEndian {int num; // 4字節char c; // 1字節(共享num的低地址空間)
};int main() {union CheckEndian u;u.num = 0x12345678;if (u.c == 0x78) {printf("小端存儲\n"); // 低地址存低字節0x78} else if (u.c == 0x12) {printf("大端存儲\n"); // 低地址存高字節0x12}return 0;
}
三. 枚舉(enum)
枚舉用于定義一組命名的常量,使代碼更具可讀性,適用于表示 “有限的狀態或選項”(如顏色、星期、錯誤碼等)
(1)定義與特性
- 定義格式:
enum 枚舉名 {常量1, 常量2, ...};
enum Weekday {MON, // 默認為0TUE, // 默認為1(前一個+1)WED = 5, // 手動賦值為5THU // 自動為6(5+1) };
- 特性:所有枚舉常量均為 int 類型,不能直接賦值給其他類型(需強制轉換)。
(2)應用場景
- 狀態標識:如
enum Status {SUCCESS, ERROR, PENDING};
,比直接用 0、1、2 更易讀。 - 限制變量取值:
enum Color {RED, GREEN, BLUE} c; c = RED;
(只能取枚舉中的值)。