1/13
Looks like no tags are added yet.
Name | Mastery | Learn | Test | Matching | Spaced | Call with Kai |
|---|
No analytics yet
Send a link to your students to track their progress
Khai báo và khởi tạo mảng một chiều.
#include <array>
// 1. Khai báo rỗng (giá trị rác nếu là kiểu POD)
std::array<int, 5> arr1;
// 2. Khởi tạo tường minh
std::array<int, 5> arr2 = {10, 20, 30, 40, 50};
// 3. Khởi tạo gọn (C++11 trở đi, compiler tự suy type)
std::array arr3 = {1, 2, 3}; // C++17 CTAD (Class Template Argument Deduction)
// 4. Khởi tạo toàn bộ phần tử = 0
std::array<double, 10> zeros = {0}; // hoặc = {}Truy cập mảng một chiều.
arr2[0] = 100; // Nhanh, KHÔNG kiểm tra bounds (UB nếu sai)
arr2.at(4) = 500; // An toàn, ném std::out_of_range nếu index sai
int val = arr2.front(); // Phần tử đầu
int last = arr2.back(); // Phần tử cuốiDuyệt mảng một chiều.
// Cách 1: Range-based for (Khuyên dùng)
for (const auto& elem : arr2) {
std::cout << elem << " ";
}
// Cách 2: Index truyền thống
for (size_t i = 0; i < arr2.size(); ++i) {
std::cout << arr2[i] << " ";
}Khai báo và khởi tạo mảng hai chiều.
// Ma trận 2 hàng, 3 cột
std::array<std::array<int, 3>, 2> matrix;
// Khởi tạo tường minh (nên dùng 2 lớp {} để tránh warning compiler cũ)
std::array<std::array<int, 3>, 2> mat = {{
{1, 2, 3}, // Hàng 0
{4, 5, 6} // Hàng 1
}};
// C++11/14 cho phép bỏ bớt {} nhưng dễ gây nhầm lẫn, nên giữ đủ
std::array<std::array<double, 2>, 3> points = {{{0.0, 1.0}, {2.0, 3.0}, {4.0, 5.0}}};Truy cập mảng hai chiều.
// Truy cập hàng 1, cột 2 (giá trị 6)
int val = mat[1][2];
// An toàn với .at()
int safeVal = mat.at(1).at(2); // mat.at(1) trả về hàng, rồi gọi .at(2) trên hàng đó
// Đổi giá trị
mat[0][0] = 100;Duyệt mảng hai chiều.
// Range-based for lồng nhau
for (const auto& row : mat) { // row là std::array<int, 3>&
for (int val : row) { // val là int
std::cout << val << "\t";
}
std::cout << "\n";
}
// Index truyền thống
for (size_t r = 0; r < mat.size(); ++r) { // mat.size() = số hàng
for (size_t c = 0; c < mat[0].size(); ++c) { // mat[0].size() = số cột
std::cout << mat[r][c] << " ";
}
std::cout << "\n";
}Phương thức size()
std::array<int, 5> arr = {1, 2, 3, 4, 5};
std::cout << arr.size(); // Output: 5Trả về constexpr size_t → giá trị xác định tại compile-time.
Không thay đổi được (mảng cố định).
✅ Dùng thay cho sizeof(arr)/sizeof(arr[0]) → rõ nghĩa, không sai.
Phương thức empty()
std::array<int, 0> empty_arr;
std::cout << std::boolalpha << empty_arr.empty(); // true
std::array<int, 3> non_empty = {1, 2, 3};
std::cout << non_empty.empty(); // falseTrả về true nếu size() == 0.
⚠ std::array có size 0 là hợp lệ (khác với con trỏ).
✅ Nên dùng if (!arr.empty()) thay vì if (arr.size() > 0) → rõ ý định hơn.
Phương thức front() / back()
std::array<int, 4> arr = {10, 20, 30, 40};
std::cout << arr.front(); // 10
std::cout << arr.back(); // 40
// Có thể sửa giá trị
arr.front() = 100; // arr = {100, 20, 30, 40}Trả về reference (T& hoặc const T&) → có thể đọc hoặc sửa.
⚠ UB nếu gọi trên mảng rỗng (size() == 0). Luôn kiểm tra empty() trước nếu không chắc.
✅ Thay thế an toàn và rõ nghĩa cho arr[0] và arr[arr.size()-1].
Phương thức data()
std::array<int, 3> arr = {1, 2, 3};
int* ptr = arr.data();
// Tương thích API C
void c_api(int* buf, size_t len);
c_api(arr.data(), arr.size());
// Sửa qua con trỏ
*ptr = 999; // arr[0] giờ là 999Trả về T* trỏ đến phần tử đầu tiên.
Bộ nhớ liên tục, giống hệt C-array → có thể dùng với memcpy, fread, OpenGL, socket...
⚠ Con trỏ trả về có thể trở thành dangling nếu arr bị hủy.
Phương thức fill(value)
std::array<int, 5> arr;
arr.fill(0); // {0, 0, 0, 0, 0}
arr.fill(-1); // {-1, -1, -1, -1, -1}Tương đương std::fill(arr.begin(), arr.end(), value) nhưng ngắn gọn hơn.
✅ Hiệu năng tối ưu: compiler có thể biến thành memset với kiểu POD.
Phương thức at(index)
std::array<int, 3> arr = {10, 20, 30};
std::cout << arr.at(1); // 20
try {
arr.at(10) = 100; // ❌ Ném ngoại lệ
} catch (const std::out_of_range& e) {
std::cerr << "Lỗi: " << e.what() << "\n";
}Kiểm tra 0 <= index < size() ở runtime.
Nếu sai → ném std::out_of_range.
✅ Dùng khi debug, hoặc dữ liệu từ nguồn không tin cậy (user input, network, file).
Phương thức operator[]
std::array<int, 3> arr = {10, 20, 30};
arr[1] = 200; // OK
int x = arr[2]; // OK
arr[10] = 999; // ❌ Undefined Behavior! Có thể crash, hoặc ghi đè bộ nhớ khácKhông kiểm tra, nhanh hơn at() một chút.
⚠ Nếu index sai → UB: crash, dữ liệu hỏng, lỗ hổng bảo mật.
✅ Dùng khi bạn đã chứng minh được index luôn hợp lệ (ví dụ: vòng lặp for (size_t i = 0; i < arr.size(); ++i)).
Phương thức swap()
std::array<int, 3> a = {1, 2, 3};
std::array<int, 3> b = {4, 5, 6};
a.swap(b);
// a = {4, 5, 6}, b = {1, 2, 3}
// Hoặc dùng hàm tự do
std::swap(a, b);Hoán đổi từng phần tử (O(N) với N là size).
✅ Hiệu quả hơn copy-gán khi mảng lớn.