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

C語言結構體指針完全指南:定義、訪問、數組指針、函數參數傳遞差異

     編輯:關於C語言

C語言結構體指針完全指南:定義、訪問、數組指針、函數參數傳遞差異

結構體指針是C語言操作聚合數據的核心手段。本文系統講解指針定義、成員訪問運算符->、結構體數組指針運算、函數參數傳值與傳址的語義差異,並給出標準代碼模板。

一、結構體指針基礎

1. 定義與賦值

struct Student {
    int id;
    char name[20];
    float score;
};

struct Student stu = {1001, "ZhangSan", 92.5};
struct Student *p = &stu; // 指向結構體變量

2. 成員訪問:->運算符

// 等價寫法
int id1 = p->id;        // 推薦:簡潔明確
int id2 = (*p).id;      // 明確解引用後訪問
// 錯誤:*p.id (優先級:. > *,會先取p.id再解引用,p無id成員)

->專為結構體指針設計,優先級與.相同,最高。

二、結構體數組指針

struct Student class[3] = {
    {1001, "A", 90}, {1002, "B", 85}, {1003, "C", 95}
};
struct Student *p = class; // 指向首元素

// 指針算術:p+1 跳過一個結構體大小
printf("%zu\n", sizeof(struct Student)); // 假設輸出 28 (含對齊)
printf("%p %p %p\n", p, p+1, p+2);      // 地址遞增 28 字節

// 遍歷數組
for (int i = 0; i < 3; i++) {
    printf("ID: %d, Name: %s\n", (p+i)->id, (p+i)->name);
}

三、運算符優先級陷阱

表達式結合順序含義
++p->id++(p->id)指針指向的結構體id成員自增
(++p)->id(++p)->id指針先移到下一結構體,再取id
p++->id(p++)->id取當前結構體id,指針後移
p->id++(p->id)++取id舊值,id自增

口訣:->、.、[]、()最高優先級;單目運算符(++、--、*、&)次之,右結合。

四、結構體作為函數參數:值傳遞 vs 指針傳遞

1. 值傳遞(傳結構體變量)

void modify_by_value(struct Student s) {
    s.id = 999; // 修改副本
    printf("in func: %d\n", s.id);
}

int main() {
    struct Student s = {1001, "A", 90};
    modify_by_value(s);
    printf("in main: %d\n", s.id); // 輸出 1001,原值不變
    return 0;
}
  • 形參獲得實參完整拷貝(按字節拷貝所有成員)。
  • 函數內修改不影響實參。
  • 大結構體拷貝開銷大,棧壓力大。

2. 指針傳遞(傳結構體地址)

void modify_by_ptr(struct Student *p) {
    p->id = 999; // 修改實參指向的內存
    printf("in func: %d\n", p->id);
}

int main() {
    struct Student s = {1001, "A", 90};
    modify_by_ptr(&s);
    printf("in main: %d\n", s.id); // 輸出 999,原值被修改
    return 0;
}
  • 形參接收實參地址,無拷貝開銷。
  • 函數內可修改實參成員,改動持久化。
  • 若不想修改,應加const:void print(const struct Student *p)。

五、最佳實踐總結

  1. 優先傳指針:避免拷貝,允許修改,語義清晰(輸入用const struct T*,輸出用struct T*)。
  2. 小結構體(≤16字節)且無修改需求可考慮傳值,利用寄存器傳遞提速。
  3. 指針運算謹慎:遍歷數組用索引p[i]或(p+i),避免手動++p易出錯。
  4. 函數返回結構體指針:絕不返回局部變量地址,需返回malloc內存、靜態變量或調用者傳入的緩衝區指針。

掌握結構體指針的定義、訪問、算術與參數傳遞語義,是編寫高效、健壯C代碼的關鍵一環。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved