以下是您提供的英文文本翻译成繁體中文的版本,使用Markdown格式:
# C 語言中的可變長度數組:初學者指南
你好,未來的程序员們!今天,我們將踏上一段令人興奮的旅程,探索 C 語言中的可變長度數組(Variable Length Arrays,簡稱 VLAs)。如果你是編程新手,別擔心——我會成為你的友好導遊,一步步地解釋一切。那麼,我們一起來看看吧!
##什麼是可變長度數組?
在我們開始之前,讓我們先了解什麼是可變長度數組。想像你正在計劃一個派對,但你不知道會有多少客人來。如果你能設置一個能夠根據客人數量神奇地調整大小的桌子,豈不是很好?這正是編程中 VLAs 所做的!
可變長度數組是一種在運行時(程序正在運行時)而不是在編譯時(程序正在準備運行時)決定大小的數組。這個特性在 C99 標準中引入,提供了在創建數組時更多的靈活性。
## 創建可變長度數組
讓我們從一個簡單的例子開始創建 VLA:
```c
#include <stdio.h>
int main() {
int n;
printf("你想存儲多少個數字? ");
scanf("%d", &n);
int numbers[n]; // 這是我們的可變長度數組
printf("輸入 %d 個數字:\n", n);
for (int i = 0; i < n; i++) {
scanf("%d", &numbers[i]);
}
printf("你輸入了:");
for (int i = 0; i < n; i++) {
printf("%d ", numbers[i]);
}
return 0;
}
讓我們分解這段代碼:
- 我們問用戶他想存儲多少個數字。
- 我們根據用戶的輸入創建一個名為
numbers
的數組,大小為n
。 - 我們然後使用一個循環從用戶那裡輸入
n
個數字。 - 最後,我們打印出用戶輸入的所有數字。
這就是 VLAs 的美妙之處——我們在寫代碼時不需要知道數組的大小。大小是在程序運行時決定的!
二維可變長度數組
現在,讓我們升級一下,看看二維 VLAs。想像你正在為一場婚禮創建座位表,但你不知道會有多少張桌子或者每張桌子有多少個座位。二維 VLAs 可以幫助我們!
這裡有一個例子:
#include <stdio.h>
int main() {
int tables, seats;
printf("有多少張桌子? ");
scanf("%d", &tables);
printf("每張桌子有多少個座位? ");
scanf("%d", &seats);
int seating[tables][seats]; // 我們的 2D 可變長度數組
// 分配座位號碼
for (int i = 0; i < tables; i++) {
for (int j = 0; j < seats; j++) {
seating[i][j] = i * seats + j + 1;
}
}
// 打印座位安排
printf("\n座位安排:\n");
for (int i = 0; i < tables; i++) {
printf("桌子 %d: ", i + 1);
for (int j = 0; j < seats; j++) {
printf("%3d ", seating[i][j]);
}
printf("\n");
}
return 0;
}
在這個例子中:
- 我們問用戶有多少張桌子以及每張桌子有多少個座位。
- 我們創建一個名為
seating
的 2D VLA,維度為[tables][seats]
。 - 我們分配座位號碼。
- 最後,我們打印出座位安排。
這種靈活性讓我們能夠創建任何大小的座位表,大小在運行時決定!
鋸齒數組
現在,讓我們來看看真正有趣的部分。如果我們的婚禮上每張桌子都有不同數量的座位怎麼辦?這時,我們可以使用鋸齒數組——一個數組的數組,其中每個子數組可以有不同的長度。
雖然 C 語言不直接支持像其他一些語言那樣的鋸齒數組,但我們可以使用 VLAs 和指針來模擬它們。這樣做:
#include <stdio.h>
#include <stdlib.h>
int main() {
int tables;
printf("有多少張桌子? ");
scanf("%d", &tables);
int *seats = malloc(tables * sizeof(int));
int **seating = malloc(tables * sizeof(int*));
// 輸入每張桌子的座位數量
for (int i = 0; i < tables; i++) {
printf("桌子 %d 有多少個座位? ", i + 1);
scanf("%d", &seats[i]);
seating[i] = malloc(seats[i] * sizeof(int));
}
// 分配座位號碼
for (int i = 0; i < tables; i++) {
for (int j = 0; j < seats[i]; j++) {
seating[i][j] = j + 1;
}
}
// 打印座位安排
printf("\n座位安排:\n");
for (int i = 0; i < tables; i++) {
printf("桌子 %d: ", i + 1);
for (int j = 0; j < seats[i]; j++) {
printf("%3d ", seating[i][j]);
}
printf("\n");
}
// 釋放分配的內存
for (int i = 0; i < tables; i++) {
free(seating[i]);
}
free(seating);
free(seats);
return 0;
}
這個例子更複雜,讓我們分解一下:
- 我們創建一個名為
seats
的數組來存儲每張桌子的座位數量。 - 我們創建一個指針-to-指針
seating
來模擬我們的鋸齒數組。 - 我們根據每張桌子的座位數量動態分配內存。
- 我們分配座位號碼並像以前一樣打印座位安排。
- 最後,我們釋放分配的內存以防止內存泄漏。
這種方法讓我們每張桌子都有不同數量的座位——真正的靈活性!
方法表
這裡是我們在例子中使用的方法的快速參考表:
方法 | 描述 | 示例 |
---|---|---|
scanf() |
從用戶讀取格式化輸入 | scanf("%d", &n); |
printf() |
打印格式化輸出到控制台 | printf("你好,%s!", name); |
malloc() |
動態分配內存 | int *arr = malloc(n * sizeof(int)); |
free() |
釋放動態分配的內存 | free(arr); |
記住,能力越強,責任越大。VLAs 和動態內存分配是強大的工具,但使用時需要小心,以避免像棧溢出或內存泄漏這樣的問題。
這就是全部!你剛剛踏出了進入 C 語言中可變長度數組世界的第一步。記住,熟能生巧,所以不要害怕嘗試這些概念。快樂編程!
Credits: Image by storyset