陣列與多維陣列
陣列是一排並肩而立、大小相同、從 0 編號的信箱。與其為十個分數宣告十個各別變數,你宣告一個十格的陣列,並用索引指稱每一格。這些格子在記憶體中緊鄰彼此,這正是讓索引快速且可預測的原因。
你用型別、名字、與方括號裡的大小來宣告陣列:「int scores[5];」造出五個 int 格子,以 scores[0] 到 scores[4] 存取。索引從 0 數起,所以最後一個有效索引是大小減一。元素在記憶體中連續:scores[i] 位於基底位址加上 i 乘以一個 int 的大小。多維陣列是陣列的陣列:「int grid[3][4];」是 3 列 4 行,以 grid[row][col] 定址,並在記憶體中一列接一列地排放(列主序)。C 並未在陣列旁邊任何地方儲存長度,也不檢查你的索引——越界會讀寫到鄰近的記憶體。
為什麼重要與核心提醒:陣列是字串、緩衝區、表格的基石,但它們缺乏邊界檢查是 C 最鋒利的邊緣之一。一個差一錯誤或越過尾端的索引就是緩衝區溢位——一種可能損毀資料、當掉、或開出安全漏洞的未定義行為。再兩個誠實的細節:在多數運算式中陣列名字會退化成指向其首元素的指標(所以你把它傳給函式時長度就遺失了——你必須另外傳長度),而對陣列本身用 sizeof 得到整個陣列的位元組大小,對指向它的指標用則不然。
int scores[5] = {90, 85, 70, 60, 95}; int third = scores[2]; /* 從 0 數索引:這是 70 */ int grid[2][3] = {{1,2,3},{4,5,6}}; int cell = grid[1][2]; /* 第 1 列、第 2 行:這是 6 */ /* scores[5] 會越界:未定義行為 */
索引從 0 到大小減一;二維陣列一列接一列地儲存。存取 scores[5] 越過尾端——是未定義行為,而非會被攔下的錯誤。
C 不儲存陣列的長度,也不對索引做邊界檢查——越界是未定義行為(緩衝區溢位)。傳給函式時陣列退化成指標、長度遺失,所以你必須自己把長度傳過去。