If you're new to C++, you've probably met arrays and found them a bit annoying. Their size is fixed, so if you need to store one more item than you planned, you're stuck. Vectors fix that problem.
This guide explains what vectors are and how to use them, one small step at a time. No prior knowledge needed.
What Is a Vector in C++?
A vector is a container that holds a list of items, like numbers or letters. Think of it as a magic shopping list: you can add items, cross them off, and the list stretches or shrinks to fit.
Here's what makes vectors useful:
- They grow and shrink automatically. You don't have to decide the size in advance.
- You can jump to any item instantly. Asking for the 3rd item is just as fast as asking for the 300th.
- Adding or removing at the end is fast.
- They manage their own memory. You don't have to do it yourself, which is great when you're learning.
Vectors come from the C++ Standard Template Library (STL), a toolbox of ready-made containers and functions that comes with C++.
Your First Vector
To use vectors, add #include <vector> at the top of your program.
#include <iostream>
#include <vector>
using namespace std;
int main()
{
vector<int> v = {10, 20, 30, 40};
for (int x : v) {
cout << x << " ";
}
return 0;
}
Output:
10 20 30 40
What's happening here:
vector<int> vcreates a vector namedvthat stores whole numbers (int).{10, 20, 30, 40}fills it with starting values.for (int x : v)means "for each item inv, call itxand do something with it." Here we print it.
The Basic Syntax
vector<T> v;
Tis the type of data you want to store (int,char,double,string, and so on).vis just a name. You can call it anything.
Adding Elements
There are two main ways to add items:
push_back(value)adds an item to the end. It's very fast (O(1) on average).insert(position, value)adds an item anywhere you choose. It's slower (O(n)) because the vector has to shift other items over to make room.
What's O(1) and O(n)? This is "Big O" notation, a way to describe how fast something is. O(1) means the time stays about the same no matter how big the vector is. O(n) means the time grows as the vector grows. You don't need to master this yet. Just remember that O(1) is faster.
#include <iostream>
#include <vector>
using namespace std;
int main() {
vector<char> v = {'a', 'f', 'd'};
// Add 'z' at the end
v.push_back('z');
// Add 'c' at index 1 (the second spot)
v.insert(v.begin() + 1, 'c');
for (char i : v)
cout << i << " ";
return 0;
}
Output:
a c f d z
Note that v.begin() + 1 means "the start of the vector, moved over by one spot." Counting in C++ starts at 0, so index 1 is the second position.
Accessing Elements
You can read an item in two ways:
v[i]is quick, but it doesn't check whetheriis valid.v.at(i)checks first. If the index doesn't exist, it throws an error (std::out_of_range) instead of quietly doing something wrong.
Both take O(1) time. As a beginner, at() is a safer choice while you're learning, because it tells you when you've made a mistake.
#include <iostream>
#include <vector>
using namespace std;
int main()
{
vector<int> v = {10, 20, 30, 40};
// Using []
cout << "Element at index 2 using []: " << v[2] << endl;
// Using at()
cout << "Element at index 3 using at(): " << v.at(3) << endl;
// This would cause an out_of_range error, because
// there is no index 10 in this vector:
// cout << v.at(10) << endl;
return 0;
}
Output:
Element at index 2 using []: 30
Element at index 3 using at(): 40
Updating Elements
To change an item, use its index and the = sign:
#include <iostream>
#include <vector>
using namespace std;
int main()
{
vector<int> v = {10, 20, 30};
cout << "Original value at index 1: " << v[1] << endl;
// Change the value at index 1
v[1] = 50;
cout << "Updated value at index 1: " << v[1] << endl;
return 0;
}
Output:
Original value at index 1: 20
Updated value at index 1: 50
Finding the Size of a Vector
Use size() to see how many items are inside:
#include <iostream>
#include <vector>
using namespace std;
int main() {
vector<char> v = {'a', 'c', 'f', 'd', 'z'};
cout << v.size();
return 0;
}
Output:
5
Looping Through a Vector
"Traversing" just means visiting every item, one by one. You have three options:
- A regular
forloop with an index (v[i]) - A range-based
forloop (the easiest, and what we've been using) - Iterators (a more advanced tool you can learn later)
Looping through everything takes O(n) time, which makes sense because there are n items to visit.
#include <iostream>
#include <vector>
using namespace std;
int main() {
vector<char> v = {'a', 'c', 'f', 'd', 'z'};
for (char i : v)
cout << i << " ";
return 0;
}
Output:
a c f d z
Two handy tips:
- Use
for (char &x : v)when you want to change the items. The&means you're working with the real item, not a copy. - Use
for (const char &x : v)when you only want to read the items. It avoids making copies, which is more efficient.
Removing Elements
pop_back()removes the last item. It's fast (O(1)).erase()removes an item (or a range of items) from anywhere. It's usually O(n), because the items after it have to shift to fill the gap.
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main() {
vector<char> v = {'a', 'c', 'f', 'd', 'z'};
// Remove the last element ('z')
v.pop_back();
// Find 'f' and remove it
v.erase(find(v.begin(), v.end(), 'f'));
for (int i = 0; i < v.size(); i++) {
cout << v[i] << " ";
}
return 0;
}
Output:
a c d
We included <algorithm> here because find() lives there. It searches the vector and tells erase() which item to remove.
Checking If a Vector Is Empty
empty() returns true if there's nothing inside and false if there is:
#include <iostream>
#include <vector>
using namespace std;
int main() {
vector<int> v;
if (v.empty()) {
cout << "Vector is empty." << endl;
}
v.push_back(100);
if (!v.empty()) {
cout << "Vector is not empty. First element: " << v[0] << endl;
}
return 0;
}
Output:
Vector is empty.
Vector is not empty. First element: 100
It's good practice to check empty() before accessing items, so you don't try to read something that isn't there.
Multidimensional Vectors (Grids and Tables)
Sometimes one row of data isn't enough. A game board, a spreadsheet, or a seating chart all need rows and columns. For that, you can put a vector inside another vector, which is called a 2D vector.
vector<vector<int>> matrix;
Here's an example:
#include <iostream>
#include <vector>
using namespace std;
int main() {
vector<vector<int>> matrix = {
{1, 2, 3},
{4, 5, 6},
{7, 8, 9}
};
// Loop through each row, then each value in that row
for (const auto &row : matrix) {
for (const auto &val : row) {
cout << val << " ";
}
cout << endl;
}
return 0;
}
Output:
1 2 3
4 5 6
7 8 9
auto tells C++ to work out the type for you, which saves typing when types get long.
Quick Reference Cheat Sheet
| What you want to do | Function | Speed |
|---|---|---|
| Add to the end | push_back(value) |
O(1) average |
| Add anywhere | insert(position, value) |
O(n) |
| Read an item | v[i] or v.at(i) |
O(1) |
| Change an item | v[i] = newValue |
O(1) |
| Get the count | size() |
O(1) |
| Remove the last item | pop_back() |
O(1) |
| Remove from anywhere | erase() |
O(n) |
| Check if empty | empty() |
O(1) |
Why Use Vectors?
- Flexible size: They grow and shrink as your program runs.
- Fast access: Any item is available instantly by its index.
- Less hassle: The vector handles memory for you.
- Works with the STL: You can use it with sorting, searching, and other built-in tools.