Giao diện
🚫 Modern Arrays — Stop Using C-arrays!
C-style arrays (
int arr[]) là legacy. Modern C++ dùng std::vector và std::array — an toàn hơn và mạnh mẽ hơn. Vấn đề với C-arrays
1. Không biết size
cpp
void process(int arr[]) {
// ❌ Không có cách nào biết size của arr!
// sizeof(arr) = sizeof(pointer), KHÔNG phải array size
}
int main() {
int arr[5] = {1, 2, 3, 4, 5};
process(arr); // arr decays to pointer!
return 0;
}2. Array Decay
cpp
int arr[5] = {1, 2, 3, 4, 5};
std::cout << sizeof(arr) << std::endl; // 20 (5 * sizeof(int))
// Khi pass to function, DECAYS to pointer
void func(int* p) {
std::cout << sizeof(p) << std::endl; // 8 (pointer size)
}
func(arr); // Lost size information!3. No bounds checking
cpp
int arr[5] = {1, 2, 3, 4, 5};
arr[10] = 100; // ❌ No error! Buffer overflow!
arr[-1] = 0; // ❌ No error! Undefined behavior!4. Cannot copy/assign
cpp
int a[5] = {1, 2, 3, 4, 5};
int b[5];
// b = a; // ❌ Error: cannot assign arrays
// Phải copy manually
for (int i = 0; i < 5; ++i) {
b[i] = a[i];
}5. No iterators/algorithms
cpp
int arr[5] = {5, 2, 8, 1, 9};
// ❌ Không thể dùng range-based for trực tiếp với function params
// ❌ Không có .begin(), .end(), .size()
// Phải dùng C-style:
for (int i = 0; i < 5; ++i) {
std::cout << arr[i] << " ";
}std::array — Fixed-size Array (C++11)
std::array là wrapper cho C-array với đầy đủ STL interface.
cpp
#include <array>
#include <iostream>
#include <algorithm>
int main() {
// Declaration (size must be compile-time constant)
std::array<int, 5> arr = {1, 2, 3, 4, 5};
// ✅ Knows its size
std::cout << "Size: " << arr.size() << std::endl; // 5
// ✅ Bounds checking
std::cout << arr.at(2) << std::endl; // 3
// arr.at(10); // ❌ Throws std::out_of_range
// ✅ Range-based for
for (const auto& elem : arr) {
std::cout << elem << " ";
}
// ✅ STL algorithms
std::sort(arr.begin(), arr.end());
auto it = std::find(arr.begin(), arr.end(), 3);
// ✅ Can be copied/assigned
std::array<int, 5> arr2 = arr; // Copy!
return 0;
}std::array vs C-array
| Feature | C-array | std::array |
|---|---|---|
| Size known | ❌ Decays | ✅ .size() |
| Bounds check | ❌ No | ✅ .at() |
| Copyable | ❌ No | ✅ Yes |
| Assignable | ❌ No | ✅ Yes |
| Iterators | ❌ No | ✅ Yes |
| Pass by value | ❌ Decays | ✅ Works |
| Performance | ✅ Zero-cost | ✅ Zero-cost |
| Stack allocated | ✅ Yes | ✅ Yes |
📌 Zero Overhead
std::array có no runtime overhead so với C-array. Compiler optimizes it completely.
std::vector — Dynamic Array
Khi không biết size lúc compile-time:
cpp
#include <vector>
#include <iostream>
std::vector<int> readNumbers() {
std::vector<int> nums;
int n;
while (std::cin >> n) {
nums.push_back(n); // ✅ Dynamic growth
}
return nums; // ✅ Can return by value (move semantics)
}
int main() {
std::vector<int> v = {1, 2, 3, 4, 5};
// ✅ All array features plus:
v.push_back(6); // Dynamic add
v.pop_back(); // Dynamic remove
v.resize(10); // Change size
v.reserve(100); // Pre-allocate
// ✅ Range-based for
for (const auto& elem : v) {
std::cout << elem << " ";
}
return 0;
}Khi nào dùng std::array vs std::vector?
| Use Case | Container |
|---|---|
| Size known at compile time | std::array |
| Size unknown/dynamic | std::vector |
| Performance-critical fixed-size | std::array |
| Need to resize | std::vector |
| Stack allocation required | std::array |
| Very large data | std::vector (heap) |
Migration Guide
Before (C-style)
cpp
// ❌ Old C-style
void processData(int data[], int size) {
for (int i = 0; i < size; ++i) {
data[i] *= 2;
}
}
int main() {
int arr[5] = {1, 2, 3, 4, 5};
processData(arr, 5); // Must pass size separately!
return 0;
}After (Modern C++)
cpp
// ✅ With std::array
void processData(std::array<int, 5>& data) {
for (auto& elem : data) {
elem *= 2;
}
}
// ✅ Or generic with std::span (C++20)
void processData(std::span<int> data) {
for (auto& elem : data) {
elem *= 2;
}
}
// ✅ Or with std::vector
void processData(std::vector<int>& data) {
for (auto& elem : data) {
elem *= 2;
}
}std::span — View into Contiguous Memory (C++20)
cpp
#include <span>
#include <vector>
#include <array>
#include <iostream>
// Works with ANY contiguous container!
void print(std::span<const int> data) {
for (int x : data) {
std::cout << x << " ";
}
std::cout << std::endl;
}
int main() {
int c_arr[] = {1, 2, 3};
std::array<int, 3> std_arr = {4, 5, 6};
std::vector<int> vec = {7, 8, 9};
// All work!
print(c_arr); // 1 2 3
print(std_arr); // 4 5 6
print(vec); // 7 8 9
// Subspan
print(std::span(vec).subspan(1, 2)); // 8 9
return 0;
}2D Arrays
C-style (Avoid)
cpp
// ❌ Painful with functions
void process(int arr[][5], int rows) {
// Second dimension must be compile-time constant!
}Modern C++
cpp
// ✅ std::array of std::array (fixed)
std::array<std::array<int, 4>, 3> matrix = {{
{1, 2, 3, 4},
{5, 6, 7, 8},
{9, 10, 11, 12}
}};
// ✅ std::vector of std::vector (dynamic)
std::vector<std::vector<int>> grid(3, std::vector<int>(4, 0));
grid[1][2] = 42;
// ✅ Flat std::vector (performance)
int rows = 3, cols = 4;
std::vector<int> flat(rows * cols);
flat[row * cols + col] = 42; // Access [row][col]HPN Standard Rules
📌 Array Guidelines
- Mặc định: Dùng
std::vector - Fixed size compile-time: Dùng
std::array - Never: Dùng raw C-arrays (trừ khi C interop)
- Prefer: Pass by
const&hoặcstd::span(C++20) - Remember:
std::array= stack,std::vector= heap
Performance Comparison
cpp
#include <array>
#include <vector>
#include <chrono>
// Both have O(1) random access
// std::array: Slightly faster initialization (no heap)
// std::vector: Slightly slower due to heap allocation
// In practice: Difference is negligible
// Choose based on requirements, not micro-optimization📚 Tổng kết
| Container | Use When |
|---|---|
C-array int[] | ❌ Never (legacy only) |
std::array<T, N> | Fixed size, compile-time known |
std::vector<T> | Dynamic size, default choice |
std::span<T> | View into any contiguous memory (C++20) |
🎉 Hoàn thành Part 4: STL Containers!
Bạn đã nắm vững:
- ✅
std::vectorvới size/capacity - ✅
std::stringvới SSO và operations - ✅
std::map/unordered_map - ✅ Big O analysis
- ✅ Iterators và invalidation
- ✅ Modern arrays
Tiếp theo: Part 5 — Modern C++ (Smart Pointers, Move Semantics, Lambdas)