Semorphe

vector

一排東西,而且長度可以變。 · ⏱ 約 30 分鐘

你會學到三件事

  1. vector長度會變的陣列
  2. push_back 往後面加、size() 問現在幾個
  3. 範圍 for:不管位置,只要每一個

開始之前

第 13 課的陣列有一個硬限制:格數在寫程式的時候就要決定

int n;
cin >> n;
int a[n];     // ⚠️ 標準 C++ 不允許

而「要幾格」常常要等程式跑起來才知道。vector 解決這件事。

一、一開始是空的

vector<int> v;
這一段 意思
vector 一排會變長的東西
<int> 裡面每一格裝整數
v 名字

⚠️ 沒有 [5]——它一開始是空的,一格都沒有。

積木盤上這一顆寫著「建立 … 列表 …」。

那個角括號 <int> 是新的寫法。它的意思是「這個 vector 是裝 int 的」。 換成 vector<string> 就是裝字串的。

二、往後面加

v.push_back(3);
v.push_back(1);
v.push_back(4);
cout << v.size() << endl;    // 3

又是第 14 課那個「點」的寫法——唸成「的」v.size() 就是「vsize」。 點的左邊是誰,右邊是問它什麼/叫它做什麼。

寫法 做什麼
v.push_back(x) 最後面加一個 x,長度加一(積木上:「在 … 尾端加入 …」)
v.size() 現在有幾個
v.back() 最後一個是什麼
v.pop_back() 把最後一個丟掉,長度減一

⚠️ v.pop_back() 不會把那個值還給你——它只是丟掉。 要先 v.back() 拿到再 pop_back()

三、拿第幾個

和陣列一模一樣:

cout << v[0] << endl;    // 3

位置一樣從 0 開始,v[v.size()] 一樣不存在。 ⚠️ vector 也不會攔你越界——它跟陣列一樣危險。

四、範圍 for

想走過每一個而不在乎位置的時候,有更短的寫法:

for (int x : v) {
    cout << x << endl;
}

讀法:「v 裡面的每一個 x,做這件事。」

積木盤上這一顆就寫著「對每個 …」——它的名字就是它的讀法。

它和 for (int i = 0; i < v.size(); i++) 走的是同一批東西。 把兩支並排看,差別只有一個地方

for (int i = 0; i < v.size(); i++) {
    cout << v[i] << endl;      // ← 要用 v[i] 才拿得到值
}
for (int x : v) {
    cout << x << endl;         // ← x 本身就是那個值
}

🔴 這是最容易搞混的一件事

i  是【位置】     0, 1, 2, 3 ...     要拿值得寫 v[i]
x  是【值】       90, 85, 72 ...     它就是值,不用再查一次

⚠️ 所以 for (int x : v) cout << v[x];錯的—— 那變成「拿第 90 個」,而 v 根本沒有第 90 個。 而它不會報錯,只會印出一個莫名其妙的數字。

換個角度想i 是座位號碼,x 是坐在那個位子上的人。 用座位號碼要先去查是誰;拿到人就直接是人了。

拿得到位置 適合什麼
for (int i = 0; ...) 要知道「這是第幾個」
for (int x : v) 只要每一個值——不會寫錯邊界

不需要位置的時候用範圍 for。 少一個地方會寫錯,就是少一個 bug。

完成的樣子

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

1#include <iostream>2#include <vector>3using namespace std;4int main() {5    vector<int> v;6    v.push_back(3);7    v.push_back(1);8    v.push_back(4);9    cout << v.size() << endl;10    for (int x : v) {11        cout << x << endl;12    }13    return 0;14}
314列表v的長度換行變數x換行印出0回傳對每個intxv印出v尾端加入v尾端加入v尾端加入建立int(整數)列表v大小每格填複製自定義函式 回傳型別int(整數)main使用命名空間std引入函式庫vector(動態列表)引入函式庫iostream(輸入輸出)123456789101113

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

換你了

改成讀進使用者輸入的數字,直到輸入 0 為止,然後印出總共幾個。

提示:while (true) + 讀一個 + if (x == 0) break;push_back

到編輯器做這一題:練習:讀到 0 為止,印出總共幾個

做一個

讀進一串數字,讀到 0 為止。印出平均(整數除法),再印出高於平均的有幾個

🔴 這一題非得走兩趟不可:第一趟不知道平均是多少,所以算不出第二個答案。 先試著用一趟做做看,卡住的地方就是這一題要教的東西。 ⚠️ 裁判用的是 10 20 30 40 0

到編輯器做這一題:做一個:有幾個人高於平均

這一課你做了什麼

如果卡住了

你看到 多半是因為
vector 說沒宣告 目標不是 C++(C 沒有 vector)——看一下右下角
v[0] 拿到怪東西 vector 一開始是空的。要先 push_back
範圍 for 改了值卻沒生效 for (int x : v)x複本。要改要寫 for (int& x : v)
範圍 for 印出一堆怪數字 寫成 v[x] 了。x 已經是值,不是位置
size() 比預期少一 pop_back() 多做了一次
在編輯器打開這一課 →