Semorphe

陣列

一個名字,裝一整排東西。 · ⏱ 約 30 分鐘

你會學到三件事

  1. 一個名字怎麼裝很多個值
  2. 陣列和 for 迴圈為什麼是天生一對
  3. 越界:拿一個不存在的位置會發生什麼

開始之前

先別往下讀。 先到編輯器做這一題:先試試看:一百個人怎麼辦,用你現在會的東西:

五個人的分數是 3、1、4、1、5。印出最高的那一個。

你會的夠了:五個變數,加上 if 一個一個比。做得出來。

做出來之後,把同一個做法改成一百個人。

⚠️ 這一題沒有裁判,也不會有人說你對或錯。它要你撞上去的是下面那一段。


改不動吧。

int a1 = 3, a2 = 1, a3 = 4, a4 = 1, a5 = 5;

而問題不是打字很累。問題是每個名字都不一樣,所以 for 迴圈幫不上忙: 迴圈會的是「同一件事做很多次」,而這裡每一次要碰的是不同的名字。

這一課給你的,就是讓那一整排共用一個名字。

🟢 先把編輯器打開,跟著下面一起做:跟著做

一、宣告一排

照著打上這一行:

1int a[5] = {3, 1, 4, 1, 5};
531415建立int(整數)陣列a大小初始值1
這一段 意思
int 裡面每一格都是整數
a 這一整排的名字
[5] 五格
= {3, 1, 4, 1, 5} 一開始各裝什麼

二、拿第幾格

要拿其中一格,用方括號加上編號:

🔎 這一段是試一下——打了看結果就好,不要留在程式裡。

1cout << a[0] << endl;    // 3   ← 第一格2cout << a[4] << endl;    // 5   ← 第五格,也是最後一格
變數a0陣列的第 [] 格換行變數a4陣列的第 [] 格換行0回傳印出印出定義函式 回傳型別int(整數)main使用命名空間std引入函式庫iostream(輸入輸出)12

⚠️ 又是第 11 課那件事:位置從 0 開始。

   3     1     4     1     5
  a[0]  a[1]  a[2]  a[3]  a[4]
                            ↑ 五格,而最後一格是 [4]

a[5] 不存在,而 C++ 不會攔你。 它會給你旁邊那塊記憶體裡 剛好放著的東西,可能是垃圾、可能讓程式當掉、也可能看起來一切正常。

這是 C++ 最危險的一件事,而它不會報錯。

三、陣列和 for 是天生一對

方括號裡面可以放變數:

1int sum = 0;2for (int i = 0; i < 5; i++) {3    sum = sum + a[i];4}5cout << sum << endl;     // 14
005變數sum變數sum變數a變數i陣列的第 [] 格+把設成變數sum換行0回傳印出計數i從到(不含)重複宣告int(整數)變數sum=定義函式 回傳型別int(整數)main使用命名空間std引入函式庫iostream(輸入輸出)1235

i 從 0 走到 4,a[i] 就依序是每一格。

第 11 課那個形狀現在有意義了:

🔎 這一段是試一下——打了看結果就好,不要留在程式裡。

1for (int i = 0; i < 5; i++)2              ↑3       正好走過 [0] 到 [4],一格不多一格不少
0回傳定義函式 回傳型別int(整數)main使用命名空間std13

⚠️ 寫成 i <= 5 的話,最後一圈會碰到 a[5],那一格不存在。

四、格數要寫成一個名字

格數寫成一個名字,改的時候只要改一個地方:

const int N = 5;
int a[N] = {3, 1, 4, 1, 5};
for (int i = 0; i < N; i++) { ... }

const 的意思是「這個值不准改」。

積木盤上它是另一顆,寫著「宣告常數 …」。

好處是:想改成 10 格的時候只要改一個地方。 把 5 散在三處的話,改漏一處就是越界,而它不會報錯。

完成的樣子

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

1#include <iostream>2using namespace std;3int main() {4    int a[5] = {3, 1, 4, 1, 5};5    int sum = 0;6    for (int i = 0; i < 5; i++) {7        sum = sum + a[i];8    }9    cout << sum << endl;10    return 0;11}
531415005變數sum變數sum變數a變數i陣列的第 [] 格+把設成變數sum換行0回傳印出計數i從到(不含)重複宣告int(整數)變數sum=建立int(整數)陣列a大小初始值定義函式 回傳型別int(整數)main使用命名空間std引入函式庫iostream(輸入輸出)1234567910

把積木打散,自己排回去:排回去:把剛才那支程式的積木排好

換你了

找出這五個數字裡最大的那個。

提示:先假設第一個是最大的(int mx = a[0];), 然後從第二個開始一個一個比,比它大就換掉。

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

做一個

有 1 到 5 號五位候選人。先讀進票數 n,再讀 n 張票(每張是一個號碼)。 印出每個人的得票(號碼 票數,五行),最後印 當選 X。

⚠️ 裁判用的是 7 張票:3 1 3 5 3 1 2。

🔴 先別急著用陣列。 想一下如果用五個變數 c1 c2 c3 c4 c5 要寫成什麼樣子, 再回頭看陣列版——那個差別就是這一課存在的理由。 ⚠️ 而平手怎麼辦這一題沒有規定。你自己決定,然後跟旁邊的人比一下你們的規則。

到編輯器做這一題:做一個:投票統計

這一課你做了什麼

如果卡住了

你看到 多半是因為
總和多了一個怪數字 迴圈跑到 a[5] 了。條件應該是 i < 5
程式莫名其妙當掉 越界寫入(a[10] = 1;)——它會踩到別人的記憶體
int a[n] 說 n 不是常數 格數要是編譯時就知道的值。用 const int 或第 15 課的 vector
最大值答案是 0 mx 從 0 開始了。要從 a[0] 開始(負數的時候 0 會是錯的)
在編輯器打開這一課 →