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

C語言結構體進階(二):結構體指針、結構體數組指針、指針作函數參數

     編輯:C 語言基礎

結構體指針


struct Student { int num; char *name; char sex; float score; };
struct Student stu = {101, "Zhang", 'M', 85.5};
struct Student *pstu = &stu;  // 取結構體變量地址
// 錯誤:pstu = &Student;  // 結構體標籤無地址

成員訪問三種等價形式


stu.num;           // 1. 變量直接訪問
(*pstu).num;       // 2. 解引用後訪問,括號必不可少
pstu->num;         // 3. 箭頭運算符(推薦)

(*pstu).num 中括號不可省:*pstu.num 解析為 *(pstu.num),結構體指針無 num 成員,編譯錯誤。

結構體數組指針


struct Student class[5] = {...};
struct Student *ps = class;  // ps 指向首元素
// ps+1 -> class[1], ps+i -> class[i]
for (ps = class; ps < class+5; ++ps) {
    printf("%d %s %c %.1f\n", ps->num, ps->name, ps->sex, ps->score);
}
  • 指針算術單位為 sizeof(struct Student),自動跨越整個結構體。
  • 不可 讓結構體指針指向單個成員:ps = &class[0].score; 類型不匹配。

結構體指針作函數參數:高效傳遞

結構體整體傳值會拷貝所有成員(含數組),開銷大。傳指針僅拷貝地址 (4/8 字節),且允許函數修改原數據。

示例:統計平均分與不及格(指針版)


void stats(struct Student *ps) {
    float sum = 0; int fail = 0;
    for (int i=0; i<5; ++i, ++ps) {
        sum += ps->score;
        if (ps->score < 60) ++fail;
    }
    printf("總分: %.1f, 平均: %.2f, 不及格: %d\n", sum, sum/5, fail);
}

int main() {
    struct Student class[5] = {...};
    stats(class);  // 數組名退化為指針
    return 0;
}

對比:值傳遞 vs 指針傳遞

維度值傳遞 void f(struct S s)指針傳遞 void f(struct S *p)
參數拷貝整個結構體(所有成員)僅地址 (4/8 字節)
函數內修改修改副本,不影響原值修改原對象
性能大結構體開銷大極低開銷
只讀意圖天然只讀需 const struct S *p 表達

指針遍歷的兩種風格


// 風格 1:索引 + 指針
for (int i=0; iscore
}

// 風格 2:純指針範圍
struct Student *end = ps + n;
for (; ps < end; ++ps) {
    ps->score;
}

風格 2 更符合 C 風格,無索引變量,編譯器易優化。

總結

  • 結構體指針聲明:struct Tag *ptr;,賦值取變量地址 &var。
  • 成員訪問:-> 最簡潔,(*p).m 需括號,*p.m 錯誤。
  • 結構體數組指針自動按結構體大小步進,遍歷極其高效。
  • 函數參數首選指針,大結構體更是如此;只讀加 const。
  • 指針不可指向成員,只能指向整個結構體或數組元素。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved