嵌套結構是構建複雜數據模型的基石,允許將一個結構類型作為另一個結構的成員。本文詳細講解嵌套結構的定義順序、成員訪問鏈式語法、初始化策略,並給出學生-地址實戰模型。
/* 1. 先定義內層結構 addr */
struct addr {
char city[20];
unsigned long zipcode;
char tel[14];
};
/* 2. 再定義外層結構 student,嵌入 addr */
struct student {
char name[8];
int age;
struct addr address; /* 嵌套成員 */
} stu1, stu2; /* 直接定義變量 */
/* 或分離標籤與變量 */
struct student {
char name[8];
int age;
struct addr address;
};
struct student stu1, stu2;
注意:struct addr address; 中的 addr 是類型標籤,address 是成員名,兩者名字空間獨立,可同名但不建議。
語法:外層變量.內層變量.最內層成員
stu1.address.zipcode = 200001; /* 賦值 */
printf("%s", stu1.address.city); /* 讀取 */
/* 若有指針 */
struct student *ps = &stu1;
ps->address.zipcode = 100000; /* 箭頭運算符等價於 (*ps).address.zipcode */
遞歸原則:無論嵌套多少層,**從最外層變量出發,逐層點選成員名**,直到目標標量成員。
struct student stu = {
"Zhang", 20,
{ "Beijing", 100086, "12345678" } /* 內層用大括號包裹 */
};
struct student stu = {
.name = "Li",
.address.zipcode = 510000 /* 跳過中間成員 */
};
strcpy(stu.name, "Wang");
stu.age = 22;
stu.address.zipcode = 430000;
struct addr {
char province[16];
char city[16];
char district[16];
char detail[64];
unsigned long zipcode;
};
struct student {
long id;
char name[32];
int age;
char gender; /* 'M'/'F' */
struct addr home; /* 戶籍地址 */
struct addr school; /* 學校地址 */
float gpa;
};
void print_student(const struct student *s) {
printf("ID:%ld Name:%s Age:%d GPA:%.2f\n", s->id, s->name, s->age, s->gpa);
printf(" Home: %s %s %s %s %lu\n",
s->home.province, s->home.city, s->home.district, s->home.detail, s->home.zipcode);
}
| 錯誤代碼 | 問題 | 修正 |
|---|---|---|
struct student { struct addr address; }; 未先定義 addr | 編譯錯誤:未知類型 | 先定義 addr 或前置聲明 struct addr;(僅限指針成員) |
stu.address.zipcode = 1234567890; | 超出 unsigned long 範圍 | 確認數值範圍或改用 uint64_t |
scanf("%s", stu.address.city); 無長度限制 | 緩衝區溢出風險 | scanf("%15s", stu.address.city); |
| 嵌套結構作為函數參數傳值 | 大結構拷貝開銷大 | 傳遞指針 const struct student* |
嵌套結構以「類型組合」方式建模現實世界層級關係(學生-地址、訂單-商品-供應商等)。掌握**定義順序**、**鏈式訪問**、**大括號初始化**、**記憶體展開佈局**四大核心,配合指針傳遞避免拷貝開銷,即可靈活構建任意複雜度的數據模型。