Variable-Length Array (C99):數組維度可由運行時變量指定,而非編譯期常量。注意:創建後大小不可變,「變」指定義時的靈活性,非動態調整大小。
void func(int n) {
int a[n]; // 一維 VLA
int b[n][m]; // 二維 VLA (m 也為變量)
// int c[n] = {0}; // 錯誤:VLA 不允許初始化列表
}
malloc。參數列表中先聲明維度變量,再聲明數組:
// 完整原型 void show(int rows, int cols, double arr[rows][cols]); // 原型可省略變量名,用 * 佔位 void show(int, int, double [*][*]); // C99 標準寫法 void show(int rows, int cols, double arr[][cols]); // 等價,前一維可省略
#includevoid copy_mat(int rows, int cols, double src[rows][cols], double dst[rows][cols]) { for (int i = 0; i < rows; ++i) for (int j = 0; j < cols; ++j) dst[i][j] = src[i][j]; } void show_mat(int rows, int cols, double mat[rows][cols]) { for (int i = 0; i < rows; ++i) { for (int j = 0; j < cols; ++j) { printf("%.1f%c", mat[i][j], j==cols-1?'\n':','); } } puts("--------------------------"); } int main(void) { double a[3][5] = {{2.3,1.2,5.2,6.1,1.1},{4.2,3.2,6.2,1.7,7.4},{8.5,6.2,4.7,2.8,2.1}}; double b[5][12] = {{4.3,4.3,4.3,3.0,2.0,1.2,0.2,0.2,0.4,2.4,3.5,6.6}, ...}; double ta[3][5], tb[5][12]; copy_mat(3, 5, a, ta); show_mat(3, 5, ta); copy_mat(5, 12, b, tb); show_mat(5, 12, tb); return 0; }
rows * cols * sizeof(T) 字節,通過運行時計算偏移訪問元素。cols * sizeof(T)。| 特性 | VLA | malloc |
|---|---|---|
| 生命周期 | 自動(作用域結束釋放) | 手動控制 |
| 大小限制 | 棧大小 (通常 1-8MB) | 堆大小 (GB 級) |
| 分配速度 | 極快 (指針移動) | 較慢 (系統調用) |
| 失敗處理 | 棧溢出崩潰 (難捕獲) | 返回 NULL 可檢查 |
| 適用場景 | 中小、生命周期短、尺寸不固定 | 大、長生命周期、需跨函數持有 |
C11 將 VLA 標記為條件性特性(__STDC_NO_VLA__ 可為 1),編譯器可選擇不支持。現代嵌入式/安全關鍵代碼建議避免 VLA,改用 malloc + 靜態分析工具檢查。
malloc 更安全可控。