首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C >> C 語言入門

C語言結構體深度解析:定義、初始化、賦值、訪問與記憶體佈局

     編輯:C 語言入門

結構體本質:用戶定義的聚合類型

將異構基本類型(int、float、char[] 等)按固定順序打包,形成新的類型模板,便於表達現實世界實體的多屬性特徵。

定義語法與標籤


// 完整定義:帶標籤,可復用
struct Book {
    int price;
    char title[44];
};

// 定義同時聲明變量
struct Book { int price; char title[44]; } a, b;

// 匿名結構:無標籤,僅能在定義處聲明變量,不可復用
struct { int price; char title[44]; } c;

// 推薦:typedef 簡化類型名
typedef struct Book {
    int price;
    char title[44];
} Book;

Book b1, b2; // 直接用 Book

標籤作用:賦予類型身份,支援自我引用(鏈表節點)、跨文件聲明、避免匿名結構「同樣成員卻是不同類型」的問題。

初始化方式


// 順序初始化
Book b1 = { 43, "C Primer" };

// 指定初始化器 (C99) —— 順序無關、可選擇性初始化
Book b2 = { .title = "Modern C", .price = 59 };
Book b3 = { .price = 30 }; // title 自動歸零

// 嵌套結構初始化
typedef struct { int x, y; } Point;
typedef struct { Point center; int r; } Circle;
Circle c = { .center = {10, 20}, .r = 5 };

賦值規則

  • 結構體變量間可直接賦值:b2 = b1; 執行逐字節拷貝(淺拷貝)。
  • 不支援字面量賦值:b2 = {.price=10}; 僅在初始化時合法,C23 才引入複合字面量賦值。
  • 指針指向結構體:Book *p = &b1; p->price = 99;。

成員訪問三種等價形式


Book b = {10, "Test"};
Book *p = &b;

b.price;      // 1. 直接訪問
p->price;     // 2. 指針解引用訪問(最常用)
(*p).price;   // 3. 顯式解引用後訪問
// 結論:p->m 等價於 (*p).m,前者語法糖更簡潔。

記憶體佈局與對齊


struct Demo {
    char c;     // 偏移 0
    int i;      // 偏移 4 (對齊填充 3 字節)
    double d;   // 偏移 8 (對齊填充 0 字節,假設 8 字節對齊)
};
// sizeof(Demo) = 24 (尾部填充至最大對齊倍數)
  • 成員按聲明順序佈局,地址遞增。
  • 編譯器插入填充字節滿足對齊要求(通常為類型大小)。
  • #pragma pack(n) 或屬性 `__attribute__((packed))` 可壓縮佈局(網絡協議、硬體寄存器映射常用),但可能降低訪問速度或觸發硬體異常。

靜態/全局結構體初始化限制

  • 靜態存儲期變量(全局/static)必須用常量表達式初始化。
  • 自動存儲期變量(局部非 static)可用變量表達式初始化。

柔性數組成員 (C99)


struct Packet {
    int len;
    char data[]; // 末端不定長數據
};
// 分配:malloc(sizeof(struct Packet) + payload_len)
// 訪問:pkt->data[i]

實現變長結構體,單次分配、連續記憶體、無指針間接開銷。

總結:結構體使用清單

  1. 用 typedef struct Tag { ... } Type; 定義可復用類型。
  2. 優先用指定初始化器(C99)提高可讀性與健壯性。
  3. 理解淺拷貝語義,指針成員賦值後雙方指向同一記憶體。
  4. 關注對齊與填充,必要時用 offsetof 宏檢查偏移。
  5. 變長數據用柔性數組 data[],而非 data[0](GCC 擴展)或指針。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved