數組提供固定大小、連續內存、下標隨機訪問的數據結構。C 語言數組下標從 0 開始,長度不可變 (VLA 除外)。
int arr[10]; // 10個int,未初始化 (垃圾值)
int arr[10] = {0}; // 全部初始化為 0
int arr[] = {1,2,3,4,5}; // 推導長度 = 5
int arr[5] = {1,2}; // 前2賦值,其餘自動 0
// ✅ 合法:常量表達式
int a[5+3];
int b[10*2];
// ❌ 非法:變量作為長度 (C90),VLA (C99 可選,非標準)
int n = 10;
int c[n]; // 依賴編譯器支持,避免使用
int a[10];
a[0] = 1; // 首元素
a[9] = 10; // 末元素
// a[10] = 11; // ❌ 越界!未定義行為,編譯器不檢查
// 變量下標
for (int i = 0; i < 10; i++) scanf("%d", &a[i]);
for (int i = 9; i >= 0; i--) printf("%d ", a[i]);
char c1[5] = {'H','E','L','L','O'}; // 無\0,非字符串
char c2[6] = {'H','E','L','L','O','\0'};// 手動加\0
char c3[] = "HELLO"; // 自動加\0,長度6
char c4[10] = "HELLO"; // 餘下填\0
char s[] = "Hello";
printf("%s\n", s); // 遇\0停止
printf("%zu\n", strlen(s)); // 5 (不含\0)
printf("%zu\n", sizeof(s)); // 6 (含\0)
// 手動遍歷
for (int i = 0; s[i] != '\0'; i++) putchar(s[i]);
void bubble_sort(int *a, int n) {
for (int i = 0; i < n-1; i++) {
for (int j = 0; j < n-1-i; j++) {
if (a[j] > a[j+1]) {
int t = a[j]; a[j] = a[j+1]; a[j+1] = t;
}
}
}
}
// 優化:若某輪無交換,提前結束
void reverse(char *s) {
int len = strlen(s);
for (int i = 0, j = len-1; i < j; i++, j--) {
char t = s[i]; s[i] = s[j]; s[j] = t;
}
}
// 注意:字符串字面量不可修改!須用數組 char s[] = "..."
// 返回新長度,元素前移覆蓋目標
int delete_sorted(int *a, int n, int target) {
int l = 0, r = n-1, pos = -1;
while (l <= r) {
int m = l + (r-l)/2;
if (a[m] == target) { pos = m; break; }
else if (a[m] < target) l = m+1;
else r = m-1;
}
if (pos == -1) return n; // 未找到
for (int i = pos; i < n-1; i++) a[i] = a[i+1];
return n-1;
}
// 三種等價聲明
void print(int a[]);
void print(int a[10]);
void print(int *a);
void print(int *a, int n) { // 必須額外傳長度
for (int i = 0; i < n; i++) printf("%d ", a[i]);
puts("");
}
// sizeof 陷阱
void trap(int a[10]) {
printf("%zu\n", sizeof(a)); // 輸出 8 (指針大小),非 40!
}
int m[2][3] = {{1,2,3}, {4,5,6}};
m[0][1] = 99; // 第0行第1列
// 內存連續:1 2 3 4 5 6
| 陷阱 | 後果 | 防範 |
|---|---|---|
| 下標越界 | 數據破壞/崩潰/安全漏洞 | 循環條件 i < n,斷言/靜態分析 |
| 字符串無\0 | strlen/printf 越界讀 | 用字面量初始化/手動加\0 |
| 修改字面量 | 段錯誤 | 用數組 char s[] = "..." |
sizeof(參數數組) | 得到指針大小 | 顯式傳長度參數 |
| VLA 棧溢出 | 大數組耗盡棧 | 用 malloc 動態分配 |
| 未初始化讀取 | 垃圾值邏輯錯誤 | 定義即初始化 = {0} |
數組是 C 語言最高效的聚合類型。掌握聲明初始化、下標訪問、字符串\0約定、函數參數退化、經典排序查找算法,嚴守邊界檢查、初始化、\0結尾三大鐵律,能編寫高性能、安全的數組代碼。大數組、可變長度場景轉用 malloc 動態內存。