c+ + là ngôn ngữ mạnh mẽ và gần gũi với ngôn ngữ máy. Ngoài ra, C++ còn có khả năng lập trình dựa trên mẫu có sẵn (template). Một trong những điểm mạnh của C++ nằm ở STL (Standard Template Library) - một thư viện template dành cho C++ tổng hợp các cấu trúc dữ liệu cũng như giải thuật. Một trong các cấu trúc dữ liệu phổ biến trong STL là vector trong C++.
Vậy Vector trong C++ là gì?
Vector trong C++ giống dynamic array (mảng động) nhưng có khả năng tự động thay đổi kích thước khi một phần tử được chèn hoặc xóa. Vector trong C++ được xây dựng để tổ chức, lưu trữ và quản lý các phần tử một cách hiệu quả. Các phần tử vector được đặt trong một vùng chứa liên tiếp để chúng có thể được truy cập và duyệt qua bằng cách sử dụng iterator.
vector-trong-c++
Vì sao nên dùng Vector
Nếu bạn đã phát chán việc quản lý mảng động qua con trỏ trong C++ hoặc chán phải tạo mảng mới, copy các phần tử qua mảng mới, rồi lại xóa mảng cũ mỗi khi bạn muốn thay đổi kích thước mảng động, hãy để vector giúp bạn. Vector trong C++ giúp bạn quản lý mảng động một cách dễ dàng và hiệu quả.
Một số điểm nổi trội của Vector:
- Bạn không cần phải khai báo kích thước của mảng trước, vector có thể tự động nâng kích thước lên.
- Nếu bạn thêm một phần tử vào vector đã đầy, vector sẽ tự động tăng kích thước của nó để chứa phần tử mới này.
- Vector giúp bạn biết số lượng các phần tử mà bạn đang lưu trong đó.
- Bạn có thể sử dụng số phần tử âm trong vector, rất tiện lợi trong việc cài đặt các giải thuật.
Các vector được lưu trữ trong C++ như thế nào?
Để tạo một vector trong C++, bạn chỉ cần thực hiện theo cú pháp sau:
#include //... vector variable_name;
Ví dụ:
#include int main() { std::vector my_vector; }
Sau đó, bạn có thể gán giá trị cho vector như sau:
vector my_vector = {1,2,3,4,5}
Hoặc bạn cũng có thể tạo một vector rồi gán giá trị của một vector khác cho nó:
vector my_vector = {1,2,3,4,5}; vector your_vector = my_vector;
Cơ chế ngăn chặn rò rỉ bộ nhớ của Vector
Khi một biến vector rời khỏi phạm vi đoạn code mà chương trình đang chạy, nó sẽ tự động giải phóng những phần bộ nhớ mà nó kiểm soát (nếu cần). Điều này không chỉ tiện dụng (vì bạn không cần tự tay giải phóng bộ nhớ), mà nó còn giúp ngăn ngừa lỗi rò rỉ bộ nhớ (memory leaks).
void doSomething(bool earlyExit) { int *array = new int[3]{ 1, 3, 2 }; if (earlyExit) // thoát khỏi hàm return; delete[] array; // trường hợp hàm thoát sớm, array sẽ không bị xóa }
Nếu biến earlyExit
được gán là true, mảng array
sẽ không bao giờ được giải phóng và bộ nhớ sẽ bị rò rỉ. Tuy nhiên, nếu biến array
là một vector, điều này sẽ không xảy ra, bởi vì bộ nhớ sẽ được giải phóng ngay sau khi biến array
rời khỏi phạm vi đoạn code mà chương trình đang chạy (bất kể hàm có bị thoát ra sớm hay không). Điều này làm cho vector an toàn hơn nhiều so với việc bạn phải tự chú ý đến việc giải phóng bộ nhớ.
Vector tự ghi nhớ độ dài của mình
Không giống như mảng động được tích hợp sẵn của C++, mà không biết được độ dài của mảng mà nó đang trỏ tới là bao nhiêu, vector tự theo dõi độ dài của chính nó. Bạn có thể lấy được độ dài của vector thông qua hàm size()
.
#include #include void printLength(const std::vector& array) { std::cout << "The length is: " << array.size() << '\n'; } int main() { std::vector array { 9, 7, 5, 3, 1 }; printLength(array); return 0; }
Output:
The length is: 5
Tương tự với array, hàm size()
sẽ trả về một giá trị thuộc kiểu nested type (kiểu dữ liệu lồng) là size_type
, nó là một số nguyên không dấu.
Các hàm của Vectors trong C ++
Vector trong STL cung cấp cho chúng ta nhiều chức năng hữu ích khác nhau.
-
Modifiers:
push_back()
: Thêm một phần tử vào cuối vector.assign()
: Gán một giá trị mới cho các phần tử vector.pop_back()
: Xóa phần tử cuối cùng của vector.insert()
: Chèn các phần tử mới vào trước phần tử trước vị trí được trỏ bởi vòng lặp.erase()
: Xóa các phần tử theo vị trí chỉ định.emplace()
: Thêm một phần tử mới vào vị trí đã chọn.swap()
: Hoán đổi nội dung của hai vector.clear()
: Xóa tất cả các phần tử của vector.
-
Iterators:
begin()
: Trả về iterator đến phần tử đầu tiên trong vector.end()
: Trả về iterator đến sau phần tử cuối cùng trong vector.rbegin()
: Trả về reverse iterator đến phần tử cuối cùng trong vector.rend()
: Trả về reverse iterator đến phần tử đầu tiên trong vector.cbegin()
: Trả về constant iterator đến phần tử đầu tiên trong vector.cend()
: Trả về constant iterator đến phần tử cuối cùng trong vector.crbegin()
: Trả về constant reverse iterator đến phần tử cuối cùng trong vector.crend()
: Trả về constant reverse iterator đến phần tử đầu tiên trong vector.
-
Capacity:
size()
: Trả về số lượng phần tử trong vector.max_size()
: Trả về số phần tử tối đa mà vector có thể chứa.capacity()
: Trả về số phần tử được cấp phát cho vector trong bộ nhớ.resize(n)
: Thay đổi kích thước vector thành n.empty()
: Kiểm tra xem vector có trống hay không.shrink_to_fit()
: Giảm dung lượng của vector để phù hợp với kích thước của nó.reserve(n)
: Cấp phát một số dung lượng cho vector.
-
Element access:
at(g)
: Trả về một tham chiếu đến phần tử ở vị tríg
trong vector.data()
: Trả về một con trỏ trực tiếp đến bộ nhớ mảng được vector sử dụng.front()
: Trả về phần tử đầu tiên trong vector.back()
: Trả về phần tử cuối cùng trong vector.
Kết
Với những kiến thức về vector đã được tìm hiểu, hy vọng bạn đã phân biệt được các hàm khác nhau của vector và nắm được cách hoạt động của từng hàm. Vector giúp lập trình trở nên dễ dàng hơn và hiệu quả hơn trong việc quản lý và xử lý mảng động. Hãy sử dụng vector trong hầu hết các trường hợp đụng tới mảng động.
Nguồn kiến thức về vector bạn nên tham khảo:
- GeeksforGeeks
- Cplusplus
Có thể bạn muốn xem thêm:
- [Tự học C++] Giới thiệu về phạm vi(scope) của biến hoặc hàm cục bộ
- Tất tần tật về C và C++
- Tài liệu lập trình cơ bản cho người mới bắt đầu
- Phương pháp tự học lập trình cơ bản hiệu quả cho người mới
Xem thêm việc làm C++ Developer tại TopDev