以下是您提供的英文文本翻译成繁體中文的版本,使用Markdown格式:

C - Variable Length Arrays

# 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;
}

讓我們分解這段代碼:

  1. 我們問用戶他想存儲多少個數字。
  2. 我們根據用戶的輸入創建一個名為 numbers 的數組,大小為 n
  3. 我們然後使用一個循環從用戶那裡輸入 n 個數字。
  4. 最後,我們打印出用戶輸入的所有數字。

這就是 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;
}

在這個例子中:

  1. 我們問用戶有多少張桌子以及每張桌子有多少個座位。
  2. 我們創建一個名為 seating 的 2D VLA,維度為 [tables][seats]
  3. 我們分配座位號碼。
  4. 最後,我們打印出座位安排。

這種靈活性讓我們能夠創建任何大小的座位表,大小在運行時決定!

鋸齒數組

現在,讓我們來看看真正有趣的部分。如果我們的婚禮上每張桌子都有不同數量的座位怎麼辦?這時,我們可以使用鋸齒數組——一個數組的數組,其中每個子數組可以有不同的長度。

雖然 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;
}

這個例子更複雜,讓我們分解一下:

  1. 我們創建一個名為 seats 的數組來存儲每張桌子的座位數量。
  2. 我們創建一個指針-to-指針 seating 來模擬我們的鋸齒數組。
  3. 我們根據每張桌子的座位數量動態分配內存。
  4. 我們分配座位號碼並像以前一樣打印座位安排。
  5. 最後,我們釋放分配的內存以防止內存泄漏。

這種方法讓我們每張桌子都有不同數量的座位——真正的靈活性!

方法表

這裡是我們在例子中使用的方法的快速參考表:

方法 描述 示例
scanf() 從用戶讀取格式化輸入 scanf("%d", &n);
printf() 打印格式化輸出到控制台 printf("你好,%s!", name);
malloc() 動態分配內存 int *arr = malloc(n * sizeof(int));
free() 釋放動態分配的內存 free(arr);

記住,能力越強,責任越大。VLAs 和動態內存分配是強大的工具,但使用時需要小心,以避免像棧溢出或內存泄漏這樣的問題。

這就是全部!你剛剛踏出了進入 C 語言中可變長度數組世界的第一步。記住,熟能生巧,所以不要害怕嘗試這些概念。快樂編程!

Credits: Image by storyset