iT邦幫忙

2026 iThome 鐵人賽

DAY 6
0
Software Development

30 天資料結構修行:從零開始理解資料結構系列 第 6

Day 6 從一串字到多層表格:字串與多維陣列

  • 分享至 

  • xImage
  •  

C 的字串與 char 陣列

前幾天我們用陣列存放一串數字。那麼,一串文字又是怎麼存的呢?在 C 語言中,字串(string)可以放在 char 陣列裡,最後用特殊的結束標記 '\0'(空字元)表示文字到此為止。先看一個只有英文字母的例子:

char word[4] = "cat";

這個陣列的內容可以想成:

索引:       0     1     2      3
內容:      'c'   'a'   't'   '\0'

"cat" 看起來只有三個字母,卻需要四個 char 的空間。因為 '\0' 告訴處理字串的函式:「文字到這裡結束。」如果少了這個標記,這些函式就無法只靠陣列本身判斷字串在哪裡結束,可能讀到陣列範圍以外。'c' 是單一字元;"c" 則是包含 'c''\0' 的字串,兩者不同。

字串的四種基本操作

C 語言要使用下面這些函式,先在程式開頭寫 #include <string.h>

  • strlen(word):看字串有多長,不計算最後的 \0
  • strcpy(copy, word):把 word 複製到 copy
  • strcat(word, "fish"):把 "fish" 接在 word 後面。
  • strcmp(word, "catfish"):比較兩段文字;相同時回傳 0

下面用一個完整範例觀察這些操作:

#include <stdio.h>
#include <string.h>

int main(void) {
    char word[16] = "cat";
    char copy[16];

    printf("原本的字串:%s,長度:%zu\n", word, strlen(word));

    strcpy(copy, word);
    printf("複製後:%s\n", copy);

    strcat(word, "fish");
    printf("連接後:%s\n", word);

    if (strcmp(word, "catfish") == 0) {
        printf("兩個字串的內容相同\n");
    }

    return 0;
}

程式會輸出:

原本的字串:cat,長度:3
複製後:cat
連接後:catfish
兩個字串的內容相同

這裡的 strlen(word) 得到 3,指的是目前字串的長度,不是陣列的容量 16。複製後,copy"cat";連接後,word 變成 "catfish",所以比較結果是相同。比較字串內容要用 strcmp(),不能用 ==== 比較的是位址。

複製或連接時,目的陣列要放得下完整字串和最後的 \0。例如 "catfish" 要占 8 個位置;範例中的 word[16] 放得下。strcpy()strcat() 不會替我們檢查容量,字串太長就可能越界。

補充:一個 char 占用一個位元組;在這個英文範例中,一個字母剛好占一個 char。但 UTF-8 中文字通常需要多個位元組,所以 strlen() 的結果不能直接當成中文字數。

二維陣列:把資料排成表格

一維陣列只需要一個索引,例如 scores[2]。如果資料有「列」和「欄」,就可以用二維陣列來表示。下面這個陣列有兩列,每列放三個數字:

int numbers[2][3] = {
    {10, 20, 30},
    {40, 50, 60}
};

https://ithelp.ithome.com.tw/upload/images/20260920/20183409qilby8yNcB.png

圖中的 row 是列,col 是欄。[2][3] 代表 2 列、每列 3 欄,共有 2 × 3 = 6 個元素。索引都是從 0 開始,讀取時先指定 row,再指定 col。所以 numbers[1][2] 位於 row = 1col = 2,也就是圖中右下角的 60

用兩層迴圈走訪

要依照圖中的順序印出全部元素,可以使用兩層迴圈:外層選一列,內層依序走過該列的三個欄位。

#include <stdio.h>

int main(void) {
    int numbers[2][3] = {
        {10, 20, 30},
        {40, 50, 60}
    };

    for (int row = 0; row < 2; row++) {
        for (int col = 0; col < 3; col++) {
            printf("%d ", numbers[row][col]);
        }
        printf("\n");
    }

    return 0;
}

外層迴圈第一次執行時,row0,內層依序印出 10、20、30;第二次 row1,印出 40、50、60。因此輸出為:

10 20 30
40 50 60

圖上的表格只是方便理解的畫法,不代表記憶體真的分成兩排。C 語言會先連續存放第 0 列的 10、20、30,再接著存放第 1 列的 40、50、60。這種一列接著一列的排列方式稱為「列優先」(row-major order)。

三維、四維也是同一個道理

陣列不只可以有兩維。三維陣列可以先想成「好幾張二維表格疊在一起」:

int pages[2][3][4];       // 2 頁,每頁 3 列,每列 4 欄
int books[2][3][4][5];    // 2 本書,每本 3 頁,每頁 4 列,每列 5 欄

https://ithelp.ithome.com.tw/upload/images/20260920/20183409nN2KzKf1lU.png

圖中有兩層 page,每層都是 3 個 row、4 個 col,總共有 2 × 3 × 4 = 24 個元素。像 pages[1][2][3],就是選擇 page = 1row = 2col = 3,也就是日常說的第 2 層、第 3 列、第 4 欄;每個索引都從 0 開始。

到了四維,就很難再用我們熟悉的立體空間,把四個方向同時畫出來。但這不代表四維陣列無法表示:可以像 books 一樣,想成「2 本書,每本 3 頁,每頁 4 列,每列 5 欄」,或一次只畫出其中一本、其中一頁。維度增加,重點不是想像更高維的空間,而是知道每多一維,就多一個索引來選擇資料。這些圖像只是理解上的比喻;實際記憶體仍是連續排列的。

小結

字串讓我們看到 char 陣列如何存放文字,以及結束標記 '\0' 為什麼重要;多維陣列則讓資料多了列、欄等索引,方便表示表格或更深的分組。先熟練二維陣列的索引與走訪,三維、四維只要掌握「每多一維,就多一個索引」即可。

今日重點:

  • C 字串通常放在 char 陣列中,並以 \0 標示結尾。
  • strlen()strcpy()strcat()strcmp() 可處理常見的字串操作;複製與連接時要注意容量。
  • 二維陣列使用 [列][欄] 存取元素,通常以兩層迴圈走訪。
  • 多維陣列可以看成陣列的分層組合;維度增加,索引數量也跟著增加。

現在我們知道,陣列裡的資料總是緊挨著排隊;如果不排在一起,還能找到下一筆資料嗎?

下一篇就來認識鏈結串列,看看節點如何靠指標互相「牽線」,再親手串起一條從 head 出發、最後走到 NULL 的單向鏈結串列。


上一篇
Day-5 陣列的資料搬家:搜尋、插入與刪除
下一篇
Day 7 資料不用排在一起:認識鏈結串列
系列文
30 天資料結構修行:從零開始理解資料結構8
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言