在 C 語言中,當我們需要儲存一系列相同型態的資料時,陣列 (Array) 就成為一個不可或缺的工具。而字串 (String) 在 C 語言中則是一種特殊的陣列,專門用來處理文字資料。並說明如何利用 sizeof()
來檢查記憶體大小
陣列是一個由相同資料型態的元素組成的集合,這些元素在記憶體中是連續存放的。我們可以透過索引 (Index) 來存取陣列中的每一個元素。
一維陣列是最基本的陣列形式,可以想像成一列連續的儲存格。
#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;
}
宣告與初始化:
int i_ary[] = {1, 2, 3};
所示,我們可以在宣告時使用大括號 {} 提供初始值。此時,編譯器會根據初始值的數量自動計算陣列的大小(此例中為 3)。或者,我們可以像 int i_ary2[4];
這樣,明確指定陣列的大小。宣告後,可以透過索引單獨為每個元素賦值。索引 (Index):
sizeof
運算子:
sizeof(i_ary)
會回傳總共佔用的位元組數(3 個 int = 12 位元組)。sizeof(i_ary)
的結果會是 3 (元素個數) * 4 (每個 int 的大小) = 12。sizeof(i_ary2)
的結果會是 4 (元素個數) * 4 (每個 int 的大小) = 16。二維陣列可以視為「陣列的陣列」,常被用來模擬表格或矩陣結構,具有列 (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;
}
二維陣列規則宣告與存取:
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;
}
}
宣告與空元字元 \0:
\0
null 終止字元 結尾。c_str
陣列的實際內容是 H, e, l, l, o, ,, , W, o, r, l, d, !, \0
。sizeof
與字串:
\0
的存在,sizeof(c_str)
的結果會是字元數量再加 1。"Hello, World!"
共有 13 個字元,加上結尾的 \0
,所以 sizeof(c_str)
的結果是 14 (bytes)。這就是您註解中提到的「字串後方要多個空間」的原因,該空間就是為了存放 \0。printf 的 %s:
printf
遇到 %s
格式控制符號時,它會從指定的記憶體位址開始,逐一印出字元,直到遇到 \0
為止。\0
本身不會被印出來。字串陣列:
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
輸出將導致未定行為(可能繼續讀到亂碼)。