vector
一排東西,而且長度可以變。 · ⏱ 約 30 分鐘
你會學到三件事
vector 是長度會變的陣列
push_back 往後面加、size() 問現在幾個
- 範圍 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() 就是「v 的 size」。
點的左邊是誰,右邊是問它什麼/叫它做什麼。
| 寫法 |
做什麼 |
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}
到編輯器照著做一次:跟著做
換你了
改成讀進使用者輸入的數字,直到輸入 0 為止,然後印出總共幾個。
提示:while (true) + 讀一個 + if (x == 0) break; + push_back。
到編輯器做這一題:練習:讀到 0 為止,印出總共幾個
做一個
讀進一串數字,讀到 0 為止。印出平均(整數除法),再印出高於平均的有幾個。
🔴 這一題非得走兩趟不可:第一趟不知道平均是多少,所以算不出第二個答案。
先試著用一趟做做看,卡住的地方就是這一題要教的東西。
⚠️ 裁判用的是 10 20 30 40 0。
到編輯器做這一題:做一個:有幾個人高於平均
這一課你做了什麼
- 你用
vector 做了一排長度會變的東西
- 你用
push_back 加東西、size() 問長度
- 你用範圍 for 走過每一個,而沒有碰到任何位置
如果卡住了
| 你看到 |
多半是因為 |
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() 多做了一次 |
在編輯器打開這一課 →