Quá trình học và làm việc với C++, vector luôn là một trong những cấu trúc dữ liệu được sử dụng nhiều nhất nhờ tính linh hoạt và hiệu quả vượt trội. Việc hiểu rõ vector không chỉ giúp bạn thay thế mảng truyền thống một cách an toàn hơn, mà còn mở ra khả năng khai thác sức mạnh của thư viện STL trong các bài toán thực tế.
Ở nội dung dưới đây, Xanh Cloud sẽ cùng bạn tìm hiểu vector trong C++ là gì, cách sử dụng ra sao và những hàm thường gặp giúp tối ưu quá trình lập trình.
Vector trong C++ là gì?
Vector trong C++ là một mảng động (dynamic array) thuộc Standard Template Library (STL), cho phép lưu trữ và quản lý dữ liệu một cách linh hoạt hơn so với mảng truyền thống.
Khác với mảng tĩnh phải khai báo kích thước cố định ngay từ đầu, vector có khả năng tự động thay đổi kích thước trong quá trình chương trình chạy. Khi bạn thêm phần tử mới, vector sẽ tự cấp phát thêm bộ nhớ; khi xóa phần tử, nó cũng tự điều chỉnh lại dung lượng mà không cần lập trình viên can thiệp trực tiếp.
Vector lưu trữ các phần tử liên tiếp trong bộ nhớ, hỗ trợ truy cập ngẫu nhiên thông qua chỉ số giống như mảng một chiều. Ngoài các kiểu dữ liệu cơ bản như int, float, char, vector còn có thể chứa string, struct, pair hoặc thậm chí là vector khác, giúp xây dựng các cấu trúc dữ liệu phức tạp như mảng hai chiều, danh sách động một cách dễ dàng.
Nhờ khả năng tự quản lý bộ nhớ và cung cấp nhiều hàm tiện ích sẵn có, vector là một trong những container được sử dụng phổ biến nhất trong C++ hiện đại, đặc biệt khi làm việc với dữ liệu có kích thước thay đổi liên tục.
Cách khai báo Vector trong C++
Để sử dụng vector trong C++, trước hết bạn cần khai báo thư viện tương ứng trong chương trình. Vector là một container thuộc Standard Template Library (STL), vì vậy bắt buộc phải include thư viện trước khi sử dụng.
Cú pháp khai báo thư viện
#include <vector>
Thông thường, vector sẽ được sử dụng kèm với các thư viện phổ biến khác như , … tùy theo nhu cầu xử lý dữ liệu.
Cú pháp khai báo vector cơ bản
vector vector_name;
Trong đó:
- data_type là kiểu dữ liệu của các phần tử trong vector (int, float, string, pair, struct…)
- vector_name là tên vector do bạn tự đặt
Các cách khởi tạo Vector phổ biến
1. Khai báo vector rỗng
Đây là cách khai báo đơn giản nhất, vector chưa chứa phần tử nào và kích thước ban đầu bằng 0. Bạn sẽ thêm dữ liệu vào sau bằng các hàm như push_back().
vector v;
Cách này rất phù hợp khi:
- Chưa biết trước số lượng phần tử
- Dữ liệu được nhập dần trong quá trình chạy chương trình
2. Khai báo vector với kích thước cố định
Bạn có thể khởi tạo vector với số lượng phần tử xác định ngay từ đầu. Khi đó, vector sẽ tự động cấp phát bộ nhớ cho từng phần tử.
int n = 10;
vector v(n);
Lưu ý:
- Vector sẽ có n phần tử
- Các phần tử được khởi tạo với giá trị mặc định (với int là 0)
Cách này thường dùng khi:
- Đã biết trước số lượng phần tử
- Muốn truy cập trực tiếp bằng chỉ số ngay sau khi khai báo
3. Khai báo và khởi tạo giá trị ban đầu
Bạn có thể khởi tạo vector với kích thước cố định và giá trị giống nhau cho tất cả phần tử.
int n = 5;
vector v(n, 100);
Kết quả:
v = {100, 100, 100, 100, 100}
Cách này rất hữu ích khi:
- Cần tạo mảng ban đầu có giá trị mặc định cụ thể
- Giảm số dòng code so với việc gán thủ công từng phần tử
4. Khai báo vector bằng danh sách khởi tạo
Vector cho phép khởi tạo trực tiếp các phần tử ngay khi khai báo, tương tự mảng.
vector v = {1, 2, 3, 4, 5};
Cách này thường được sử dụng khi:
- Dữ liệu ban đầu đã có sẵn
- Viết code ngắn gọn, dễ đọc
5. Khởi tạo vector từ một vector khác
Bạn có thể tạo một vector mới bằng cách sao chép toàn bộ dữ liệu từ một vector đã tồn tại.
vector v1 = {10, 20, 30};
vector v2(v1);
Sau khi khởi tạo:
v2 = {10, 20, 30}
Ngoài ra, bạn cũng có thể sao chép bằng toán tử gán:
vector v3 = v1;
Cách khởi tạo này giúp:
- Dễ dàng sao chép dữ liệu
- Tránh thao tác thủ công từng phần tử
- Đảm bảo an toàn bộ nhớ
Cách nhập/xuất và truy cập phần tử trong Vector
1. Nhập dữ liệu vào Vector
Có hai cách phổ biến để đưa dữ liệu vào vector, tùy thuộc vào việc bạn đã biết trước số lượng phần tử hay chưa.
Cách 1: Sử dụng push_back() kết hợp vòng lặp
Cách này phù hợp khi bạn nhập dữ liệu động từ bàn phím và không cần khai báo trước kích thước vector.
#include
#include
using namespace std;
int main() {
vector v;
int n, x;
cout << “Nhap so luong phan tu: “; cin >> n;
for (int i = 0; i < n; i++) { cin >> x;
v.push_back(x);
}
}
Ưu điểm:
- Linh hoạt
- Không cần biết trước kích thước
- Thường dùng trong các bài toán nhập dữ liệu thực tế
Cách 2: Khai báo vector với kích thước cố định rồi nhập bằng chỉ số
Cách này phù hợp khi đã biết trước số lượng phần tử cần lưu.
int n;
cin >> n;
vector v(n);
for (int i = 0; i < n; i++) { cin >> v[i];
}
2. Truy cập phần tử trong Vector
Vector hỗ trợ nhiều cách truy cập phần tử, mỗi cách có ưu và nhược điểm riêng.
Truy cập bằng toán tử [] int x = v[2];
- Truy cập nhanh
- Không kiểm tra chỉ số hợp lệ
- Có thể gây lỗi nếu truy cập vượt phạm vi
Thường dùng khi chắc chắn chỉ số luôn đúng.
Truy cập bằng hàm at()
int x = v.at(2);
- Có kiểm tra biên
- An toàn hơn toán tử []
- Nếu chỉ số không hợp lệ, chương trình sẽ báo lỗi
Phù hợp khi xử lý dữ liệu đầu vào không chắc chắn.
Truy cập phần tử đầu và cuối
int first = v.front();
int last = v.back();
- front() trả về phần tử đầu tiên
- back() trả về phần tử cuối cùng
- Chỉ sử dụng khi vector không rỗng
3. Xuất và duyệt Vector
Duyệt bằng vòng lặp for truyền thống
for (int i = 0; i < v.size(); i++) {
cout << v[i] << ” “;
}
- Cách phổ biến, dễ hiểu
- Phù hợp với người mới học
Duyệt bằng range-based for loop (C++11 trở lên)
for (int x : v) {
cout << x << ” “;
}
- Ngắn gọn, dễ đọc
- Không cần quan tâm chỉ số
- Phù hợp khi chỉ cần đọc dữ liệu
Duyệt bằng Iterator
for (vector::iterator it = v.begin(); it != v.end(); it++) {
cout << *it << ” “;
}
Hoặc dùng auto để code gọn hơn:
for (auto it = v.begin(); it != v.end(); it++) {
cout << *it << ” “;
}
- Cách duyệt chuẩn của STL
- Cần thiết khi làm việc với các thuật toán như sort, find, erase
Các hàm Vector trong C++ phổ biến nhất
Trong C++, vector là một trong những container được sử dụng nhiều nhất của STL nhờ khả năng quản lý bộ nhớ linh hoạt, cú pháp rõ ràng và hệ sinh thái hàm phong phú. Việc nắm vững các hàm thường dùng của vector sẽ giúp bạn thao tác dữ liệu hiệu quả hơn, code gọn gàng và an toàn hơn so với mảng truyền thống.
Dưới đây là bảng tra cứu nhanh các hàm vector trong C++ phổ biến nhất, được chia theo từng nhóm chức năng để dễ học, dễ nhớ và dễ áp dụng trong thực tế.
1. Nhóm hàm thêm / xóa phần tử (Modifiers)
Nhóm hàm này dùng để thay đổi nội dung và kích thước của vector trong quá trình chạy chương trình.
push_back()
Thêm một phần tử vào cuối vector.
Đây là hàm được sử dụng nhiều nhất khi làm việc với vector.
- Độ phức tạp trung bình: O(1)
- Vector sẽ tự động mở rộng bộ nhớ nếu cần
vector v;
v.push_back(10);
v.push_back(20);
pop_back()
Xóa phần tử cuối cùng của vector.
- Không có tham số
- Không được gọi khi vector rỗng
v.pop_back();
insert()
Chèn phần tử vào vị trí bất kỳ trong vector thông qua iterator.
- Có thể chèn 1 phần tử, nhiều phần tử hoặc một dãy phần tử
- Độ phức tạp: O(N) do phải dời các phần tử phía sau
v.insert(v.begin() + 2, 99);
erase()
Xóa phần tử tại vị trí xác định hoặc xóa một đoạn phần tử.
- Phải truyền iterator
- Sau khi xóa, các phần tử phía sau sẽ được dồn lên
v.erase(v.begin() + 1);
clear()
Xóa toàn bộ phần tử trong vector, đưa vector về trạng thái rỗng.
v.clear();
Lưu ý: clear() không nhất thiết giải phóng toàn bộ bộ nhớ đã cấp phát, chỉ đưa size về 0.
2. Nhóm hàm liên quan đến kích thước và bộ nhớ (Capacity)
Nhóm hàm này giúp bạn kiểm soát số lượng phần tử và khả năng cấp phát bộ nhớ của vector.
size()
Trả về số lượng phần tử hiện có trong vector.
int n = v.size();
empty()
Kiểm tra vector có rỗng hay không.
- Trả về true nếu vector không có phần tử
- Trả về false nếu vector có ít nhất 1 phần tử
if (v.empty()) {
// vector đang rỗng
}
capacity()
Trả về dung lượng bộ nhớ hiện tại mà vector có thể chứa mà chưa cần cấp phát lại.
- capacity() ≥ size()
- Hữu ích khi tối ưu hiệu năng, tránh realloc nhiều lần
cout << v.capacity();
Những lỗi thường gặp khi sử dụng Vector
Vector là một mảng động mạnh mẽ và tiện lợi, nhưng nếu sử dụng không đúng cách, chương trình có thể gặp lỗi runtime, lỗi logic hoặc suy giảm hiệu năng. Ba nhóm lỗi dưới đây xuất hiện nhiều nhất trong thực tế.
Truy cập ngoài phạm vi (Out of range)
Đây là lỗi rất hay gặp khi bạn cố gắng truy cập một phần tử có chỉ số không tồn tại trong vector. Ví dụ, vector chỉ có n phần tử nhưng lại truy cập v[n] hoặc v[-1].
- Sử dụng toán tử [] sẽ không kiểm tra biên, có thể dẫn đến hành vi không xác định (undefined behavior).
- Hàm .at() an toàn hơn vì sẽ tự động kiểm tra chỉ số và ném ra ngoại lệ nếu vượt phạm vi.
- Lỗi này thường xuất hiện khi duyệt vector sai điều kiện vòng lặp hoặc sau khi đã erase() phần tử nhưng vẫn dùng chỉ số cũ.
Quên include thư viện
Vector là một thành phần của Standard Template Library (STL), vì vậy nếu không khai báo thư viện cần thiết, chương trình sẽ không biên dịch được.
- Lỗi biên dịch thường gặp như: vector was not declared in this scope.
- Cách khắc phục rất đơn giản: luôn đảm bảo có dòng #include ở đầu chương trình.
- Ngoài ra, nếu dùng cout, cin thì cần thêm #include để tránh lỗi tương tự.
Hiệu năng kém khi chèn hoặc xóa phần tử ở đầu/giữa vector
Vector lưu trữ dữ liệu liên tiếp trong bộ nhớ, nên khi chèn hoặc xóa phần tử không phải ở cuối, toàn bộ các phần tử phía sau phải dịch chuyển.
- Các thao tác insert() và erase() ở đầu hoặc giữa vector có độ phức tạp O(N).
- Nếu thực hiện thường xuyên trong các bài toán lớn, chương trình có thể chạy chậm đáng kể.
- Trong những trường hợp cần chèn/xóa nhiều ở đầu hoặc giữa, std::list hoặc std::deque thường là lựa chọn phù hợp hơn so với vector.
Hy vọng qua bài viết này, bạn đã nắm vững định nghĩa vector trong C++ cũng như cách sử dụng linh hoạt loại cấu trúc dữ liệu này trong lập trình. So với mảng tĩnh truyền thống, kiểu vector trong C++ mang lại sự tiện lợi vượt trội nhờ khả năng tự thay đổi kích thước và hệ thống các hàm vector trong C++ hỗ trợ tận tình từ việc quản lý bộ nhớ đến thao tác dữ liệu. Nếu bạn có bất kỳ thắc mắc nào về cách vận hành của mảng động này, hãy liên hệ với kỹ thuật Xanh Cloud qua hotline 0889.192.666 nhé!