iT邦幫忙

0

二、三天學一點點 C:來! 陣列與字串(2)

c
  • 分享至 

  • xImage
  •  

🧠 C 陣列與字串

在 C 語言中,當我們需要儲存一系列相同型態的資料時,陣列 (Array) 就成為一個不可或缺的工具。而字串 (String) 在 C 語言中則是一種特殊的陣列,專門用來處理文字資料。並說明如何利用 sizeof() 來檢查記憶體大小


🧮 陣列教學:一維與二維陣列

陣列(Arrays)

陣列是一個由相同資料型態的元素組成的集合,這些元素在記憶體中是連續存放的。我們可以透過索引 (Index) 來存取陣列中的每一個元素。

一維陣列 (One-Dimensional Arrays)

一維陣列是最基本的陣列形式,可以想像成一列連續的儲存格。

#include<stdio.h>

int main() {
    // 方法一:宣告時同時初始化
    int i_ary[] = {1, 2, 3};
    printf("i_ary 的內容為:%d %d %d\n", i_ary[0], i_ary[1], i_ary[2]);

    // 方法二:先宣告大小,再逐一賦值
    int i_ary2[4];
    i_ary2[0] = 5;
    i_ary2[1] = 10;
    i_ary2[2] = 15;
    i_ary2[3] = 20;
    printf("i_ary2 的內容為:%d %d %d %d\n", i_ary2[0], i_ary2[1], i_ary2[2], i_ary2[3]);

    // 使用 sizeof 運算子取得陣列在記憶體中的總大小 (位元組)
    printf("i_ary 的大小:%d bytes, i_ary2 的大小:%d bytes\n", sizeof(i_ary), sizeof(i_ary2));

    return 0;
}

📌 陣列宣告與存取規則:

  1. 宣告與初始化:

    • int i_ary[] = {1, 2, 3}; 所示,我們可以在宣告時使用大括號 {} 提供初始值。此時,編譯器會根據初始值的數量自動計算陣列的大小(此例中為 3)。或者,我們可以像 int i_ary2[4]; 這樣,明確指定陣列的大小。宣告後,可以透過索引單獨為每個元素賦值。
  2. 索引 (Index):

    • 陣列的索引永遠從 0 開始。對於一個大小為 N 的陣列,其有效的索引範圍是 0 到 N-1。
    • 例如,i_ary[0] 代表存取 i_ary 的第一個元素,其值為 1。i_ary2[3] 則是存取 i_ary2 的第四個(也是最後一個)元素。
  3. sizeof 運算子:

    • sizeof(陣列名稱) 會回傳整個陣列在記憶體中所佔用的總位元組數,如此例,sizeof(i_ary) 會回傳總共佔用的位元組數(3 個 int = 12 位元組)。
    • 以上述程式碼為例,假設 int 型態佔用 4 個位元組。
      • sizeof(i_ary) 的結果會是 3 (元素個數) * 4 (每個 int 的大小) = 12。
      • sizeof(i_ary2) 的結果會是 4 (元素個數) * 4 (每個 int 的大小) = 16。

二維陣列 (Two-Dimensional Arrays)

二維陣列可以視為「陣列的陣列」,常被用來模擬表格或矩陣結構,具有列 (rows) 和行 (columns) 的概念,而二維陣列 int arr[rows][cols] 記憶體中是 row-major 儲存(列優先)。

#include<stdio.h>

int main() {
    // 宣告一個 4 列 3 行的二維陣列並初始化
    int i_ary2D[4][3] = {
        {1, 2, 3}, 
        {4, 5, 6}, 
        {7, 8, 9}, 
        {10, 11, 12}
    };
    printf("i_ary2D 的內容:\n%d %d %d \n%d %d %d \n%d %d %d \n%d %d %d \n",
           i_ary2D[0][0], i_ary2D[0][1], i_ary2D[0][2],
           i_ary2D[1][0], i_ary2D[1][1], i_ary2D[1][2],
           i_ary2D[2][0], i_ary2D[2][1], i_ary2D[2][2], 
           i_ary2D[3][0], i_ary2D[3][1], i_ary2D[3][2]);

    // 宣告一個 3 列 3 行的二維陣列並逐一賦值
    int i_ary2D_2[3][3];
    i_ary2D_2[0][0] = 2; i_ary2D_2[0][1] = 4; i_ary2D_2[0][2] = 6;
    i_ary2D_2[1][0] = 8; i_ary2D_2[1][1] = 10; i_ary2D_2[1][2] = 12;
    i_ary2D_2[2][0] = 14; i_ary2D_2[2][1] = 16; i_ary2D_2[2][2] = 18;
    printf("\ni_ary2D_2 的內容:\n%d %d %d \n%d %d %d \n%d %d %d \n", 
           i_ary2D_2[0][0], i_ary2D_2[0][1], i_ary2D_2[0][2],
           i_ary2D_2[1][0], i_ary2D_2[1][1], i_ary2D_2[1][2],
           i_ary2D_2[2][0], i_ary2D_2[2][1], i_ary2D_2[2][2]);

    // 取得二維陣列的總大小
    printf("\ni_ary2D_2 的大小:%d bytes\n", sizeof(i_ary2D_2));

    return 0;
}
  1. 二維陣列規則宣告與存取:

    • 宣告語法為 資料型態 陣列名稱[列數][行數];。例如 int i_ary2D[4][3]; 表示一個擁有 4 列 (rows) 3 行 (columns) 的整數陣列。
    • 存取元素需要兩個索引:陣列名稱[列索引][行索引]。例如 i_ary2D[1][2] 代表存取第 2 列 (row index 1) 的第 3 行 (column index 2) 的元素,其值為 6。
  2. sizeof 運算子:

    • 對於二維陣列,sizeof 同樣會回傳整個陣列所佔用的總位元組數。
    • 以上述程式碼為例,sizeof(i_ary2D_2) 的結果會是 3 (列數) * 3 (行數) * 4 (每個 int 的大小) = 36。

📝 i_ary2D[4][3] 記憶體配置如下:

i_ary2D:  [0][0] [0][1] [0][2]
          [1][0] [1][1] [1][2]
          [2][0] [2][1] [2][2]
          [3][0] [3][1] [3][2]

💬 字串教學:字元陣列與字串

#include<stdio.h>

int main() {
    // 使用字串字面值初始化字元陣列
    char c_str[] = "Hello, World!";
    
    // 使用 %s 輸出整個字串
    printf("字串內容:%s \n", c_str);
    
    // 字串本身也是陣列,可用索引存取單一字元
    printf("第1個字元:%c, 第8個字元:%c \n", c_str[0], c_str[7]);
    
    // 計算字串陣列的大小,字串後方自動補上 '\0'
    printf("c_str 陣列的大小:%d bytes\n", sizeof(c_str));

    // 字串陣列 (二維字元陣列)
    char c_str_2D[3][4] = {"abc", "def", "ghi"};
    printf("\n字串陣列內容:\n%s\n%s\n%s\n", c_str_2D[0], c_str_2D[1], c_str_2D[2]);

    return 0;
}
}

📌 字串規則與注意事項:

  1. 宣告與空元字元 \0:

    • 當我們使用雙引號 " 建立一個字串(如 "Hello, World!")來初始化一個字元陣列時,編譯器會自動在字串的末尾補上 \0 null 終止字元 結尾。
    • c_str 陣列的實際內容是 H, e, l, l, o, ,, , W, o, r, l, d, !, \0
  2. sizeof 與字串:

    • 因為 \0 的存在,sizeof(c_str) 的結果會是字元數量再加 1。
    • "Hello, World!" 共有 13 個字元,加上結尾的 \0,所以 sizeof(c_str) 的結果是 14 (bytes)。這就是您註解中提到的「字串後方要多個空間」的原因,該空間就是為了存放 \0。
  3. printf 的 %s:

    • printf 遇到 %s 格式控制符號時,它會從指定的記憶體位址開始,逐一印出字元,直到遇到 \0 為止。\0 本身不會被印出來。
  4. 字串陣列:

    • 若要儲存多個字串,可以使用二維字元陣列,例如 char c_str_2D[3][4]
    • 這裡 [3] 代表可以儲存 3 個字串,[4] 代表每個字串的最大長度是 3 個字元,因為還需要保留 1 個空間給 \0。如果試圖存入像 "abcd" 這樣長度為 4 的字串,就會因為沒有空間存放 \0 而導致錯誤。

🖼️ 圖示:"abc" 在記憶體中的配置

索引:   [0]  [1]  [2]  [3]
內容:   'a'  'b'  'c'  '\0'

👀 注意:若未預留 \0,使用 %s 輸出將導致未定行為(可能繼續讀到亂碼)。



圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言