結構體作為自定義類型,同樣支援數組與指針兩種核心聚合機制。本文系統講解結構數組的定義、初始化、二維等效認知、成員訪問語法,以及結構指針的聲明、賦值、成員訪問(點運算符 vs 箭頭運算符)、動態分配陣列等實戰技巧。
/* 匿名結構標籤,直接定義數組 */
struct {
char name[8];
char sex[2];
int age;
char addr[40];
} student[40];
/* 命名結構標籤,分離類型與變量 */
struct Student {
char name[8];
char sex[2];
int age;
char addr[40];
};
struct Student student[40];
推薦第二種:類型可復用、便於聲明指針/函數參數、調試器顯示類型名。
student[0].name // 第 1 位學生姓名
student[30].age // 第 31 位學生年齡
/* 形式:結構數組變量[下標].成員名 */
student[0] 所有成員 → student[1] 所有成員 → ...struct A {
int m[3][5]; // 成員是二維陣列
float f;
char s[20];
} y[4]; // y 有 4 個元素,每元素含 3×5 int 陣列
/* 訪問 y[2] 的 m[1][4] */
y[2].m[1][4];
struct Student class[3] = {
{ "Alice", "F", 18, "Addr1" },
{ "Bob", "M", 19, "Addr2" },
{ "Carol", "F", 17, "Addr3" }
};
/* 完全初始化時可省略數組長度 */
struct Student *pstu; /* 指向 Student 類型的指針 */
可在結構定義時同步聲明:struct Student { ... } stu1, *pstu;
struct Student stu1, *pstu;
pstu = &stu1; // 正確
// pstu = &Student; // 錯誤:標籤無地址,編譯器不分配存儲空間
| 形式 | 代碼 | 備註 |
|---|---|---|
| 結構變量直接訪問 | stu1.name | 基準形式 |
| 指針解引用 + 點運算符 | (*pstu).name | 括號**不可省略**,. 優先級高於 * |
| 箭頭運算符 (語法糖) | pstu->name | 最常用、可讀性最佳 |
struct Student {
int num;
char *name;
char sex;
float score;
} boy1 = {102, "Zhang ping", 'M', 78.5}, *pstu;
main() {
pstu = &boy1;
printf("Num=%d Name=%s\n", boy1.num, boy1.name);
printf("Num=%d Name=%s\n", (*pstu).num, (*pstu).name);
printf("Num=%d Name=%s\n", pstu->num, pstu->name);
/* 三種形式輸出完全一致 */
}
struct Student *class;
int n = 100;
class = (struct Student*)malloc(n * sizeof(struct Student));
if (!class) exit(1);
for (int i = 0; i < n; i++) {
class[i].num = i + 1; // 箭頭/下標混用
sprintf(class[i].name, "Stu%d", i);
}
free(class);
優勢:運行時決定大小、非連續記憶體友好、可釋放單元素(配合鏈表)。
pstu + 1 增加 sizeof(struct Student) 位元組,指向下一結構。sizeof(*pstu) 等於結構大小(含填充)。| 錯誤 | 後果 | 修正 |
|---|---|---|
pstu->num 但 pstu 未初始化 | 野指針,崩潰/亂寫 | 賦值後使用,或初始化為 NULL |
*pstu.num 缺少括號 | 解析為 *(pstu.num),編譯錯誤 | 改為 (*pstu).num 或 pstu->num |
malloc(sizeof(pstu)) | 僅分配指針大小 (4/8B) | malloc(sizeof(*pstu)) 或 malloc(sizeof(struct Student)) |
| 結構數組作為函數參數退化為指針 | 函數內 sizeof(arr) 失效 | 額外傳遞長度參數 |
結構數組適合**固定規模、連續存儲、隨機訪問**的同質集合;結構指針配合動態分配適合**規模未知、頻繁增刪、需構建鏈表/樹/圖**的場景。掌握 .、->、(*p).m 三種訪問等價性、正確賦值規則、指針算術與動態分配模式,是 C 語言工程化編程的必備基本功。