Semorphe

二維陣列

一個位置指不到一格,那就用兩個。 · ⏱ 約 25 分鐘

你會學到三件事

  1. 兩個位置指到一格
  2. 大括號的巢狀,對應到表格的形狀
  3. 兩層迴圈走過整張表——外圈走列、內圈走行

開始之前

第 13 課的陣列是一條a[0]a[1]a[2]…… 它只有一個方向。

而成績表不是一條。它是這樣的:

           國文  英文  數學
   小明     90    85    72
   小華     78    92    88

要指到「小華的數學」,你得說兩件事:第幾個人、第幾科。

一、兩個位置指一格

int g[2][3] = {{1, 2, 3}, {4, 5, 6}};

讀法:「2 列,每列 3 個」。

大括號裡那一串在積木上叫「初始值」——一格接一格接上去。

        [0]  [1]  [2]
   [0]   1    2    3
   [1]   4    5    6

g[1][2]6——第一個方括號是列,第二個是行

大括號的巢狀對應到形狀:{{一列}, {另一列}}

⚠️ 兩個方括號是分開的兩組:g[1][2]不是 g[1, 2]。 後者在 C++ 裡不會報錯,但它做的是完全不同的事。

二、走過整張

要走過一條陣列要一個迴圈。要走過一張表,就要兩個—— 而那正是上一課的多層迴圈。

for (int i = 0; i < 2; i++) {
    for (int j = 0; j < 3; j++) {
        cout << g[i][j] << " ";
    }
    cout << endl;
}

外圈走列、內圈走行——和一維陣列的形狀完全一樣,只是做了兩次

i = 0  →  g[0][0]  g[0][1]  g[0][2]     印 1 2 3
i = 1  →  g[1][0]  g[1][1]  g[1][2]     印 4 5 6

i 走外面那個方括號,j 走裡面那個。 兩個寫反了不會報錯,它會印出另一張表(或是直接讀到界外)。

三、讀一張表進來

int g[3][3];
for (int i = 0; i < 3; i++) {
    for (int j = 0; j < 3; j++) {
        cin >> g[i][j];
    }
}

⚠️ 宣告的時候不寫初始值,那些格子裡是垃圾—— 這和第 13 課的一維陣列是同一條規則。要先填滿再用。

完成的樣子

這一課的參考做法——程式碼每一行的號碼,就印在對應的那塊積木上。

1#include <iostream>2using namespace std;3int main() {4    int g[2][3] = {{1, 2, 3}, {4, 5, 6}};5    for (int i = 0; i < 2; i++) {6        for (int j = 0; j < 3; j++) {7            cout << g[i][j] << " ";8        }9        cout << endl;10    }11    return 0;12}
123初始值456初始值0203變數g變數j變數i二維陣列[][]" "印出換行印出計數j到(不含)重複0回傳計數i到(不含)重複建立int(整數)二維陣列g列數2行數3初始值定義函式 回傳型別int(整數)main使用命名空間std引入函式庫iostream(輸入輸出)1234567911

到編輯器照著做一次:跟著做

換你了

把每一列的總和各印一行。上面那張表的答案是 615

提示:總和的變數要在外圈裡面、內圈外面歸零—— 想一下把它放到外圈外面會發生什麼事。

到編輯器做這一題:練習:每一列的總和

做一個

讀進一張 3 × 3 的表,找出裡面最大的那個數, 印出它的值,再印出它在第幾列第幾行(都從 0 算起,中間一個空白)。

⚠️ 裁判餵的是這張表:

3 1 4
1 5 9
2 6 5

🔴 想一下:如果最大的那個數出現兩次,你的程式會回報哪一個? 那沒有標準答案——但你得說得出你的程式選了哪一個、為什麼。 跟旁邊的人對一下,你們兩個的答案不一定一樣。

到編輯器做這一題:做一個:找出表裡最大的那一個

這一課你做了什麼

如果卡住了

你看到 多半是因為
印出來的表轉了 90 度 ij 寫反了
每一列的總和越來越大 總和的變數放到外圈外面了,沒有歸零
讀進來的數字是亂的 cin >> 的兩層迴圈順序跟餵進來的順序不一樣
程式當掉或值很怪 迴圈跑到界外了——g[2][3] 的合法位置只到 g[1][2]
在編輯器打開這一課 →