写 C++ 时最常遇到的问题就是:数据往哪放?普通数组长度是死的,得提前算好容量。标准库(STL)早就备好了两个最好用的容器——vector 管一串数据,map 管键值对。这节课把它们讲明白,日常九成的存数据场景就够用了。

vector:会自己长大的数组

vector 就是"长度可变的数组",用前引入头文件 <vector>:

#include <iostream>
#include <vector>
using namespace std;

int main() {
    vector<int> nums;      // 空的 int 容器
    nums.push_back(10);    // 往尾部塞元素
    nums.push_back(20);
    nums.push_back(30);

    cout << nums.size() << endl;  // 输出 3
    cout << nums[1] << endl;      // 输出 20,下标从 0 开始
    return 0;
}

push_back 是最常用的加元素方式,size() 看当前个数,取元素直接用方括号,跟普通数组一个手感。刚创建时它是空的,千万记得先加元素再取,不然越界。

初始化的几种姿势

声明的同时就能塞初始值,写法很灵活:

vector<int> a = {1, 2, 3};     // 列表初始化
vector<int> b(5, 0);           // 5 个元素,每个都是 0
vector<int> c(a);              // 拷贝 a 的全部内容

想要多大、要什么初值,一行说清楚,比 new 出来的动态数组省心得多,也不用操心 delete。

遍历:范围 for 最省事

C++11 之后推荐用范围 for 循环,不用自己管下标:

vector<string> fruits = {"苹果", "香蕉", "橘子"};
for (const string& f : fruits) {
    cout << f << endl;    // 依次输出三种水果
}

想边遍历边改元素,就去掉 const,用引用接住每个元素:

for (int& n : a) {
    n *= 2;               // 每个元素翻倍
}

删除与常用操作

vector 还有一批高频方法:

vector<int> v = {1, 2, 3, 4};
v.pop_back();              // 删掉尾部元素,v 变成 {1, 2, 3}
cout << v.front() << endl; // 输出 1,第一个元素
cout << v.back() << endl;  // 输出 3,最后一个元素
v.clear();                 // 全部清空
cout << v.empty() << endl; // 输出 1,表示已空

注意 pop_back 只能删尾巴,删中间要配合 erase 和迭代器,入门阶段先不急。

map:一个键对应一个值

map 存"键 → 值"的映射,像一本能按名字查电话的通讯录,头文件是 <map>:

#include <iostream>
#include <map>
#include <string>
using namespace std;

int main() {
    map<string, int> ages;
    ages["小明"] = 15;    // 方括号直接写入
    ages["小红"] = 14;
    cout << ages["小明"] << endl;  // 输出 15

    ages["小明"] = 16;    // 同一个键再赋值就是修改
    cout << ages.size() << endl;   // 还是 2
    return 0;
}

键必须唯一,重复写就是覆盖。有个坑要记住:用方括号访问不存在的键,map 会自动创建它(值是 0)。只想查不想建,用 count():

if (ages.count("小刚") == 0) {
    cout << "查无此人" << endl;   // 不会顺手创建"小刚"
}

遍历 map:键值对一起拿

map 遍历出来的是一个个 pair,C++17 起可以用结构化绑定一次拿两个:

for (const auto& [name, age] : ages) {
    cout << name << " " << age << endl;
    // 按键的字典序输出:小红 14 / 小明 16
}

map 内部会自动按键排序,这也是它查找快的原因。键的类型要支持比较,string 和各种数字都没问题。

小结

  • vector 是可变长数组:push_back 加、pop_back 删、size() 看个数、方括号取元素
  • 初始化可以在声明时一次给全,不用手动 new 和 delete
  • 遍历优先用范围 for;要改元素就用非 const 引用
  • map 是键值对容器:方括号读写、count() 判断键是否存在、遍历自动按键排序
  • 方括号访问不存在的键会自动创建,只查不建用 count()

下次要存"一组东西"先想 vector,要存"名字对应东西"先想 map。选对容器,一半的代码就省下来了。