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

C 語言進階:結構體與指針深度解析

     編輯:關於C

示例結構體定義

typedef struct {
    int a;
    short b[2];
} Ex2;

typedef struct EX {
    int a;
    char b[3];
    Ex2 c;
    struct EX *d;
} EX;

EX x = {10, "hi", {5, {-1, 25}}, 0};
EX *px = &x;

指針訪問機制

表達式 px 的左值與右值

  • 右值:指針變量 px 本身的內容(即地址值)
  • 左值:px 的存儲位置,可被新地址值替換
  • px + 1 不是左值(非可識別內存位置),但若 px 指向結構體數組,其右值指向下一個結構體

間接訪問 *px

  • 右值:整個結構體內容,可賦值給同類型變量、作為 . 操作符左操作數、傳遞給函數或作為返回值(但效率低)
  • 左值:結構體存儲位置,可接受新值(即所有成員更新)
  • *px + 1 非法(結構體不支持與整數加法),但 *(px + 1) 合法(若為數組元素)

結構體內存佈局與對齊

  1. 編譯器按成員聲明順序分配內存
  2. 為滿足對齊要求,成員間可能插入填充字節
  3. sizeof 返回包含填充字節的總大小
  4. 使用 offsetof(type, member)(需 <stddef.h>)獲取成員偏移量

示例:計算成員偏移

struct tiger {
    char a;
    int b;
    char c;
};

int main() {
    struct tiger x;
    int m = offsetof(struct tiger, b); // 輸出 4(假設 int 4 字節對齊)
    printf("%d\n", m);
    return 0;
}

結構體作為函數參數:三種傳遞方式對比

typedef struct {
    char product[20];
    int quantity;
    float unit_price;
    float total_amount;
} Transaction;
方式代碼示例優點缺點
值傳遞void print(Transaction t)簡單,函數內修改不影響原值拷貝開銷大(示例 32 字節),效率低
指針傳遞void print(Transaction *t)僅傳指針(4/8 字節),效率高函數可修改原值,需 const 保護
返回修改值float compute(Transaction t)避免返回整個結構體仍需傳遞整個結構體,僅適用單值計算

最佳實踐:指針 + const

void print_receipt(const Transaction *trans) {
    // 只讀訪問,編譯器防止誤修改
}

void compute_total(Transaction *trans) {
    // 需修改時不加 const
    trans->total_amount = trans->quantity * trans->unit_price;
}

總結

  • 結構體是標量,支持賦值、傳參、返回值
  • 大結構體傳參必須使用指針,配合 const 表達語義
  • 理解內存佈局、對齊、偏移量,是底層優化與調試基礎
  • 指針算術(px+1)按結構體大小步進,是數組遍歷基礎
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved