首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

C 語言陣列完全指南:聲明、初始化、多維、字串、指針退化、靜態/動態分配與邊界檢查

     編輯:關於C語言

一維陣列


// 聲明與初始化
int a[10] = {0};           // 全 0 初始化 (關鍵!)
int b[] = {1,2,3,4,5};     // 自動推導大小 (5)
int c[5] = {[2]=10, [4]=20}; // C99 指定初始化器

// 大小計算 (僅在聲明作用域有效)
size_t n = sizeof(a) / sizeof(a[0]); // 10
// 函數參數退化為指針,sizeof 失效 -> 必須傳長度

// 遍歷
for (size_t i = 0; i < n; i++) printf("%d ", a[i]);
// 字串專用:以 '\0' 結尾
char str[] = "Hello";
for (size_t i = 0; str[i]; i++) putchar(str[i]);

多維陣列 (行優先 Row-Major)


// 二維
int mat[3][4] = {
    {1,2,3,4},
    {5,6,7,8},
    {9,10,11,12}
};
// 記憶體連續:mat[0][0], mat[0][1]... mat[2][3]

// 訪問
mat[row][col]; // 編譯器轉換為 *(mat + row*COLS + col)

// 三維
int cube[2][3][4];
cube[z][y][x]; // 偏移: (z*3*4 + y*4 + x) * sizeof(int)

// 部分初始化 / 省略第一維
int mat2[][4] = {{1,2},{3,4},{5,6}}; // 3 行 4 列
// int mat3[][3][] = ...; // 錯誤:只能省略第一維

字串陣列 (字元指針陣列 vs 二維字元陣列)


// 1. 二維字元陣列:固定最大長度,資料連續,可修改內容
char names1[3][20] = {"Alice", "Bob", "Charlie"};
names1[0][0] = 'M'; // OK -> "Malice"
printf("%zu\n", sizeof(names1)); // 60 位元組

// 2. 指針陣列:指向字串常區/堆區,指針陣列本身連續
char *names2[] = {"Alice", "Bob", "Charlie"}; // 指向唯讀常區
// names2[0][0] = 'M'; // 崩潰!修改字串常量
names2[0] = "Mike";   // OK:修改指針指向
printf("%zu\n", sizeof(names2)); // 3 * sizeof(char*) = 24 (64位)

// 動態分配字串陣列
char **dyn = malloc(n * sizeof(char*));
for (int i=0; i

陣列與指針的關鍵區別

特性陣列 `int a[10]`指針 `int *p`
記憶體分配編譯期/棧/靜態區 固定大小運行期動態分配/指向現有
`sizeof`整個陣列大小 (40)指針大小 (8/4)
`&a` 類型`int (*)[10]` (陣列指針)`int **` (指針的指針)
可修改性內容可改,地址不可改 (非左值)地址可改,指向內容可改
函數參數退化為 `int *` (失去大小)本身即 `int *`

動態分配模擬陣列 (可變長度陣列 VLA / 堆分配)


// VLA (C99, C11 可選,棧上,大小受限,嵌入式慎用)
void func_vla(int n) { int vla[n]; vla[0]=1; } // n 為變數

// 堆分配 (通用、大陣列、生命週期可控)
int *dyn_arr = malloc(n * sizeof(int));
if (!dyn_arr) return -1;
dyn_arr[0] = 1;
// 用完 free(dyn_arr);

// 二維動態 (指針陣列法 - 非連續,易碎片)
int **mat = malloc(rows * sizeof(int*));
for (int i=0; i

邊界檢查與安全

  • C **不做**邊界檢查。`a[100]` 讀寫 → UB (緩衝區溢出/越界讀)。
  • 工具:AddressSanitizer (`-fsanitize=address`)、Valgrind、Clang Static Analyzer。
  • 安全函數:`snprintf`, `strncpy` (注意不保證 `\0`), `memcpy_s` (C11 Annex K)。
  • 自定義安全封裝:`#define ARRAY_SIZE(arr) (sizeof(arr)/sizeof((arr)[0]))` 配合斷言 `assert(i < ARRAY_SIZE(arr))`。

靜態/全域陣列初始化


int global_arr[100];          // 隱式全 0 初始化 (.bss 段)
static int static_arr[100];   // 隱式全 0 初始化

int local_arr[100];           // 棧上,**不初始化** (垃圾值)
int local_init[100] = {0};    // 顯式全 0 (編譯器優化為 memset)
int local_part[100] = {1,2};  // 前兩項 1,2,其餘 0

總結

陣列是 C 語言最高效、最基礎的聚合類型。掌握「靜態/棧/堆」三種分配方式、「行優先」多維佈局、「退化為指針」的函數傳遞語義、「字串陣列」兩種形式差異,並嚴守邊界檢查原則,是寫出高效、安全 C 代碼的基石。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved