struct Student st[] = { {"aaa",25,1}, {"bbb",40,0}, ... }; // 編譯時確定大小為 5
// ...
scanf("%20s", st[5].name); // 嘗試訪問第 6 個元素 (索引 5)
// num = sizeof(st)/sizeof(st[0]); // 仍為 5
C 語言數組大小在編譯期確定,運行時不可變。
struct Student st[] = {...} 由初始化列表推導出大小 5,內存佈局固定,緊隨其後可能是其他變量或棧幀。st[5] 屬於**越界訪問** (合法索引 0~4),行為未定義 (可能覆蓋其他變量、崩潰、看似正常)。sizeof(st) 是編譯期常量,永遠返回初始化時的總字節數,無法感知運行時「新增」的數據。#define MAX_STU 100
struct Student st[MAX_STU] = { ...初始5個... };
int count = 5; // 維護當前有效個數
// 新增
if (count < MAX_STU) {
scanf("%19s %d %d", st[count].name, &st[count].age, &st[count].sex);
count++;
}
struct Student *st = malloc(5 * sizeof(struct Student));
// 初始化前 5 個...
int capacity = 5, count = 5;
// 擴容函數
void addStudent(struct Student **pst, int *capacity, int *count) {
if (*count == *capacity) {
*capacity *= 2;
*pst = realloc(*pst, *capacity * sizeof(struct Student));
if (!*pst) { perror("realloc failed"); exit(1); }
}
scanf("%19s %d %d", (*pst)[*count].name, &(*pst)[*count].age, &(*pst)[*count].sex);
(*count)++;
}
// 使用
addStudent(&st, &capacity, &count);
// 遍歷用 count
for (int i=0; i
struct Node {
struct Student data;
struct Node *next;
};
// 尾插法 O(1) 新增,無擴容煩惱
| 概念 | 說明 |
|---|---|
| 靜態數組 | 編譯期定長,棧上分配,sizeof 為總字節數,不可增刪元素。 |
| 動態數組 | 堆上分配 (malloc),用指針管理,realloc 擴容,需手動維護 size/capacity。 |
| 柔性數組 (C99) | struct { int n; Student data[]; } 結構體末尾不定長數組,配合 malloc 一次性分配。 |
| sizeof 運算符 | **編譯期**計算類型/表達式佔用字節數,**不計算運行時有效長度**。 |
原代碼冒泡排序邊界有誤:j < num - i 應為 j < num - 1 - i,且交換用臨時變量而非 st[num] (越界)。
for (int i = 0; i < count - 1; i++) {
for (int j = 0; j < count - 1 - i; j++) {
if (st[j].age > st[j+1].age) {
struct Student tmp = st[j];
st[j] = st[j+1];
st[j+1] = tmp;
}
}
}