// example2_1.cpp : 手工 new/delete、qsort、比較函式指標
#include
#include
int compare(const void* a, const void* b) {
int ia = *static_cast(a);
int ib = *static_cast(b);
return (ia > ib) - (ia < ib); // 三向比較 (C++20 <=>)
}
int main() {
const int MAX = 10;
int* arr = new int[MAX];
int n = 0;
for (; n < MAX && std::cin >> arr[n]; ++n) {} // 讀取至非整數或滿
std::qsort(arr, n, sizeof(int), compare);
for (int i = 0; i < n; ++i) std::cout << arr[i] << '\n';
delete[] arr;
return 0;
}
痛點:固定大小陣列易溢位、手工記憶體管理易洩漏、`qsort` 型別不安全、比較函式冗長、擴容需手工 `realloc`、程式碼雜訊高。
// example2_2.cpp : vector + sort + 迭代器
#include
#include
#include
#include
int main() {
std::vector v;
int x;
while (std::cin >> x) v.push_back(x); // 自動擴容、RAII
std::sort(v.begin(), v.end()); // 型別安全、平均 O(N log N)
for (int i : v) std::cout << i << '\n'; // 範圍 for (C++11)
return 0;
}
質變**:`vector` 自動管理記憶體、`sort` 型別安全且泛型、`push_back` 擴容策略 (通常 2x) 攤還 O(1)、範圍 for 簡潔遍歷、**程式碼行數減半、可讀性大增、Bug 面積銳減**。
// example2_3.cpp : istream_iterator + back_insert_iterator + ostream_iterator + copy + sort
#include
#include
#include
#include
int main() {
using InIt = std::istream_iterator;
using OutIt = std::ostream_iterator;
using Vec = std::vector;
using BackIn = std::back_insert_iterator;
Vec v;
std::copy(InIt(std::cin), InIt(), BackIn(v)); // 輸入 → 容器 (自動擴容)
std::sort(v.begin(), v.end()); // 就地排序
std::copy(v.begin(), v.end(), OutIt(std::cout, "\n")); // 容器 → 輸出
return 0;
}
極致抽象**:
| 組件 | 角色 | 核心介面 | 應用場景 |
|---|---|---|---|
| `vector` | 動態陣列容器 | `push_back`/`emplace_back`/`data()`/`size()`/`capacity()` | 順序存取、隨機存取、緩衝區、堆疊 |
| `sort` | 通用排序演算法 | `sort(RandomIt first, RandomIt last, Compare=std::less<>) ` | 任何支援隨機存取迭代器的序列 |
| `istream_iterator | 輸入流適配器 | `operator++` (前綴/後綴)、`operator*`、`operator->` | 從 `cin`/`ifstream`/`stringstream` 讀取型別化資料 |
| `ostream_iterator | 輸出流適配器 | `operator=` (寫入)、`operator++` (空操作) | 向 `cout`/`ofstream`/`ostringstream` 寫入型別化資料 |
| `back_insert_iterator | 容器尾插適配器 | `operator=` (調用 `c.push_back(val)`) | 演算法輸出目的端為需動態擴容的容器 |
| `copy` | 範圍拷貝演算法 | `copy(InputIt first, InputIt last, OutputIt d_first)` | 任意輸入範圍 → 任意輸出迭代器 |
// C++20 Ranges + Views + 管道語法
#include
#include
#include
#include
#include
int main() {
std::vector v;
// 輸入範圍 → 視圖 → 容器
std::ranges::copy(std::views::istream(std::cin), std::back_inserter(v));
std::ranges::sort(v);
// 容器 → 視圖 → 輸出
std::ranges::copy(v, std::ostream_iterator(std::cout, "\n"));
// 或一氣呵成 (C++23 ranges::to)
// auto v = std::views::istream(std::cin) | std::ranges::to();
// std::ranges::sort(v);
// std::ranges::copy(v, std::ostream_iterator(std::cout, "\n"));
}
優勢**:`views::istream` 直接建構輸入範圍、管道語法 `|` 表達資料流向、`ranges::sort` 接受範圍而非迭代器對、**組合性更強、意圖更清晰**。
從 `qsort` + 比較函式指標 → `vector` + `sort` + 迭代器 → `copy` + 適配器 + 演算法,**每一次躍升都是抽象層級的提升**——**將「如何做」封裝為組件,開發者專注「做什麼」**。這正是 **泛型程式設計 (GP) 與 STL 核心哲學**:演算法與資料結構分離、以迭代器為膠水、零成本抽象、組件化複用。