結構體指針是C語言操作聚合數據的核心手段。本文系統講解指針定義、成員訪問運算符->、結構體數組指針運算、函數參數傳值與傳址的語義差異,並給出標準代碼模板。
struct Student {
int id;
char name[20];
float score;
};
struct Student stu = {1001, "ZhangSan", 92.5};
struct Student *p = &stu; // 指向結構體變量
->運算符// 等價寫法
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自增 |
口訣:->、.、[]、()最高優先級;單目運算符(++、--、*、&)次之,右結合。
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;
}
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)。const struct T*,輸出用struct T*)。p[i]或(p+i),避免手動++p易出錯。malloc內存、靜態變量或調用者傳入的緩衝區指針。掌握結構體指針的定義、訪問、算術與參數傳遞語義,是編寫高效、健壯C代碼的關鍵一環。