結構體是 C 語言組織異構數據的核心機制。本文從定義語法、初始化規則、賦值語義、指針訪問三種形式、柔性數組成員、對齊實測六個維度,構建結構體完全使用手冊。
// 帶標籤:可自引用、跨文件聲明
struct Book {
int price;
char title[44];
};
// 無標籤:僅能在定義時同時聲明變量
struct { int x; int y; } point;
// 聲明
struct Book b1, b2;
// 初始化:順序匹配、指定初始化器 (C99)
struct Book b3 = { 50, "C Primer" };
struct Book b4 = { .title = "Modern C", .price = 80 };
// 部分初始化:其餘字段自動置 0
struct Book b5 = { .price = 30 }; // title 全 \0
// 全局/靜態變量必須常量表達式初始化
static struct Book g_book = { 100, "Global" };
struct Book a = {1, "A"}, b;
b = a; // 合法:逐字節拷貝所有成員 (指針成員拷貝地址)
// ❌ 不能用賦值列表:b = {2, "B"}; // 僅初始化時允許
// ❌ 不能比較:if (a == b) // 錯誤
struct Book book = {20, "Effective C"};
struct Book *ptr = &book;
// 1. 直接訪問
book.price = 25;
// 2. 指針箭頭操作符 (最常用)
ptr->price = 30;
// 3. 解引用後點操作符
(*ptr).price = 35;
// 遞歸結構體
struct Node { int val; struct Node *next; };
struct Node n1 = {1, NULL}, n2 = {2, &n1};
n2.next->val; // 1
struct Packet {
uint16_t len;
uint8_t data[]; // 無大小,必須為最後一個成員
};
// 分配:結構體 + 可變數據
struct Packet *pkt = malloc(sizeof(struct Packet) + 100);
pkt->len = 100;
memcpy(pkt->data, payload, 100);
// 釋放單次 free 即可
free(pkt);
優勢:單次分配、緩存局部性佳、無雙重指針間接訪問。
#include <stdio.h>
struct A { char c; int i; short s; }; // 12 字節 (x86-32)
struct B { char c; short s; int i; }; // 8 字節
struct C { double d; int i; }; // 16 字節 (double 8 對齊)
int main() {
printf("A=%zu B=%zu C=%zu\n", sizeof(struct A), sizeof(struct B), sizeof(struct C));
// 輸出: A=12 B=8 C=16
return 0;
}
struct Flags {
unsigned int ready : 1;
unsigned int error : 1;
unsigned int mode : 2; // 0-3
unsigned int reserved : 28;
}; // 總共 4 字節
struct Flags f = {1, 0, 2, 0};
if (f.ready) { /* ... */ }
| 錯誤 | 後果 | 修正 |
|---|---|---|
| 結構體定義末尾漏分號 | 編譯錯誤/後續聲明解析異常 | 加分號 |
| 柔性數組非最後一個成員 | 編譯錯誤 | 移至末尾 |
| 指針成員賦值後雙方 free | Double Free | 明確所有權/引用計數 |
| 直接比較結構體變量 | 編譯錯誤 | 逐字段比較或 memcmp (注意填充字節) |
| 跨平台傳輸結構體未處理對齊/端序 | 數據解析錯誤 | #pragma pack + hton/ntoh 序列化 |
struct Tag { ... }; + typedef struct Tag TypeName; 分離定義。{ .field = val },抗重構。// owned / // borrowed。#pragma pack(1) 並手動處理端序。const Struct*,避免棧拷貝開銷。結構體看似簡單,實則承載著內存佈局控制、類型系統邊界、序列化契約、所有權語義等系統級關鍵決策。精通結構體,即精通 C 語言的數據建模核心。