vector 是「動態數組的動態數組」,外層 vector 存儲內層 vector 對象,每個內層 vector 獨立管理自己的內存與大小。
vector> matrix; // 空矩陣
// 方式 A:構建臨時行再 push_back (推薦,清晰)
vector row;
row.push_back(1);
row.push_back(2);
matrix.push_back(row); // 第 0 行: [1, 2]
row.clear();
row.push_back(3);
row.push_back(4);
row.push_back(5);
matrix.push_back(row); // 第 1 行: [3, 4, 5]
// 方式 B:直接用初始化列表 (C++11)
matrix.push_back({6, 7});
matrix.push_back({8, 9, 10});
// 方式 C:預分配行數 (性能優化)
matrix.resize(10); // 10 個空行
matrix[0].push_back(100); // 直接操作第 0 行
// 範圍 for (C++11, 推薦)
for (const auto& row : matrix) {
for (int val : row) {
cout << val << ' ';
}
cout << '\n';
}
// 迭代器 (傳統)
for (auto it = matrix.begin(); it != matrix.end(); ++it) {
for (auto it2 = it->begin(); it2 != it->end(); ++it2) {
cout << *it2 << ' ';
}
cout << '\n';
}
// 下標訪問
for (size_t i = 0; i < matrix.size(); ++i) {
for (size_t j = 0; j < matrix[i].size(); ++j) {
cout << matrix[i][j] << ' ';
}
cout << '\n';
}
// 獲取行數
size_t rows = matrix.size();
// 獲取某行列數
size_t cols = matrix[0].size(); // 假設非空
// 修改元素
matrix[1][2] = 999;
// 在指定行插入元素
matrix[0].insert(matrix[0].begin() + 1, 99); // 第 0 行索引 1 處插入 99
// 刪除行
matrix.erase(matrix.begin() + 1); // 刪除第 1 行
// 刪除某行的元素
matrix[0].erase(matrix[0].begin()); // 刪除第 0 行首元素
// 扁平化為一維 vector
vector flat;
for (const auto& row : matrix) {
flat.insert(flat.end(), row.begin(), row.end());
}
matrix (vector>) - 棧上對象
├─ _M_impl._M_start → 堆內存: [ vector#0, vector#1, ... ]
│
├─ vector#0 (第 0 行) - 棧上對象 (在堆數組中)
│ └─ _M_impl._M_start → 堆內存: [ 1, 2 ]
│
├─ vector#1 (第 1 行)
│ └─ _M_impl._M_start → 堆內存: [ 3, 4, 5 ]
│
└─ ...
每行獨立分配內存,**非連續塊**,行長度可不一 (鋸齒數組)。
matrix.reserve(1000); row.reserve(10); 減少擴容拷貝。assign/resize。vector flat(rows * cols); flat[i*cols + j] 緩存局部性更好。matrix.push_back(std::move(row)); 避免行拷貝 (C++11)。| 錯誤代碼 | 問題 | 修正 |
|---|---|---|
vector 以為是 3x4 矩陣 | 共享同一行對象!修改 m[0][0] 會影響 m[1][0] | 用循環構建:vector |
m[0].push_back(1); 未先 resize/保證行存在 | 越界訪問,未定義行為 | 先 m.resize(1); 或 m.push_back({}); |
返回引用 vector 後外部存儲 | vector 擴容導致引用失效 | 返回拷貝、索引、或用 shared_ptr |
C++ 二維 vector 通過 push_back 構建鋸齒數組,核心模式是構建行 → push_back 行 → 遍歷行內元素。掌握範圍 for 遍歷、預分配優化、扁平化替換、避免共享行對象陷阱,即可高效靈活處理動態矩陣數據。現代 C++ (C++11/17/20) 提供的初始化列表、結構化綁定、移動語義讓代碼更簡潔安全。