struct Rec { int x, y; };
struct Rec rs[10];
for (size_t i = 0; i < sizeof rs / sizeof rs[0]; i++) {
rs[i].x = i;
rs[i].y = i * 2;
}
struct Rec {
char name[12];
short age;
} rs[3] = {
{"AAA", 11},
{"BBB", 22},
{"CCC", 22}
};
struct Rec *p = rs; // 指向首元素
printf("%s, %d\n", p->name, p->age); // rs[0]
printf("%s, %d\n", (p+1)->name, (p+1)->age); // rs[1]
p+1 會按 sizeof(struct Rec) 跳躍,指向下一元素。
struct Rec { char name[12]; short age; };
struct Rec *p = malloc(sizeof(struct Rec));
strcpy(p->name, "ABC"); // 或 stpcpy
p->age = 99;
printf("%s, %d\n", p->name, p->age);
printf("%s, %d\n", (*p).name, (*p).age); // 等價寫法
free(p);
struct Rec { int x, y; } *p;
size_t count = 10;
p = malloc(sizeof(struct Rec) * count);
for (size_t i = 0; i < count; i++) {
(p+i)->x = i;
(p+i)->y = i * i;
}
for (size_t i = 0; i < count; i++)
printf("%d, %d\n", (p+i)->x, (p+i)->y);
free(p);
for (size_t i = 0; i < count; i++) {
p[i].x = i;
p[i].y = i * i;
}
for (size_t i = 0; i < count; i++)
printf("%d, %d\n", p[i].x, p[i].y);
p[i] 編譯器自動轉換為 *(p+i),語義完全等價,可讀性更強。
malloc(sizeof(Rec)*n) 分配連續 n 個 Rec 空間。p 既是指向首元素的指標,也是動態數組的「句柄」。p[i]、(p+i)-> 兩種訪問方式,推薦統一用下標。| 形式 | 內存位置 | 大小確定性 | 生命週期 | 訪問方式 |
|---|---|---|---|---|
靜態數組 Rec a[10] | 棧/數據段 | 編譯期固定 | 作用域/程序 | a[i].mem |
指向靜態數組 Rec *p=a | 同上 | 同上 | 同上 | p[i].mem |
單個動態 malloc(sizeof(Rec)) | 堆 | 運行期決定 | 手動 free | p->mem |
動態數組 malloc(sizeof(Rec)*n) | 堆 | 運行期決定 | 手動 free | p[i].mem |
NULL,解引用導致崩潰。struct { int len; char data[]; } 需 malloc(sizeof(Struct)+len),非固定大小數組。sizeof(Rec) 已含填充,無需手動加填充。free(p); p = NULL; 良好習慣。結構體數組提供固定大小、連續存儲的聚合;結構體指標配合 malloc 實現動態大小、堆上生命週期管理。動態分配的連續結構體本質即動態數組,統一使用下標訪問 p[i] 最清晰。掌握靜態/動態、單個/數組四種組合及其內存語義,是 C 語言數據結構實戰的核心基本功。