2026/3/18 code

CPP-Primer-Chapter03

C++ Primer 标准库类型

#coding

string::size_type

string::size_type 是 string 专门用于“长度/下标”的类型,本质是无符号整数,通常等价于 size_t

为什么不用 int

  1. s.size() 返回无符号类型,和 int(有符号)比较会触发警告。
  2. int 容量可能不够(常见 32 位),size_type 会随平台自动适配。
  3. 可移植性更好,避免平台差异带来的长度问题。
string s = "hello";
string::size_type len = s.size();  // 正规写法
string s = "hello";
for (int i = 0; i < s.size(); i++) {  // ⚠️ 警告:有符号与无符号比较
    ...
}

经典陷阱:无符号下溢

string s = "hello";
string::size_type len = s.size();  // len = 5,无符号

len - 10;  // ⚠️ 不是 -5!而是一个巨大的正数(下溢)

无符号数不能表示负值,0 - 1 会回绕成很大的正数。

常见危险场景:

for (string::size_type i = s.size() - 1; i >= 0; i--) {
    // ⚠️ 死循环!i 是无符号数,永远 >= 0
    // 当 i = 0 再减 1,会变成一个巨大的数,循环不会停止
}

推荐写法

现代 C++ 建议让编译器推断类型,或直接使用范围 for

string s = "hello";

auto len = s.size();          // 自动推断为 string::size_type

for (auto i = 0u; i < s.size(); i++) {  // 用无符号的 0u
    ...
}

// 或者直接用范围 for,完全绕开索引问题
for (char c : s) {
    ...
}

倒序遍历若必须用下标,避免 i >= 0 这种写法。

cctype头文件

cctype 提供字符分类与转换函数,常见形式是:

  1. 判断类:isalphaisdigitisspaceisalnum 等。
  2. 转换类:tolowertoupper

这些函数返回非零表示条件成立,返回 0 表示不成立。

常用函数示意:

图片描述

备注:cctype 对应 C 里的 ctype.h,功能基本一致;在 C++ 中通常使用 cctype

vector

值初始化

vector<int> v(5);  // v 中有 5 个元素,自动初始化为 0
vector<Warrior> w(5);  // w 中有 5 个 Warrior 对象,调用默认构造函数

常用方法

a.size();  // 返回当前元素数量
a.push_back(x);  // 在末尾添加元素 x
a.pop_back();  // 删除末尾元素
a.empty();  // 判断是否为空

迭代器

标准库为每一个容器提供了迭代器,类似于指针,可以用来访问容器中的元素。

vector<int> v = {1, 2, 3, 4, 5};
vector<int>::iterator it = v.begin();  // 获取指向第一个元素的迭代器
while (it != v.end()) {
    cout << *it << " ";  // 通过解引用访问元素
    ++it;  // 移动到下一个元素
}

自增与解引用

迭代器支持自增(++it)和解引用(*it),使得遍历容器非常方便。

还有const迭代器(vector<int>::const_iterator)用于只读访问。

bitset

#include <bitset>
using std::bitset;

初始化与赋值

bitset<8> b1;  // 默认初始化,所有位为 0
bitset<8> b2(42);  // 从整数初始化,二进制表示为 00101010
bitset<8> b3("10110011");  // 从字符串初始化,字符串长度必须不超过 8 位
bitset<16> b4(0xffff);  // 16 位全为 1

操作

b1.set(3);  // 将第 3 位(从 0 开始)设置为 1
b1.reset(3);  // 将第 3 位重置为 0
b1.flip(3);  // 翻转第 3 位
b1.test(3);  // 测试第 3 位是否为 1
b1.count();  // 统计 bitset 中值为 1 的位数
b1.size();  // 返回 bitset 的位数(这里是 8)

b1.any(); //有无位为1
b1.none(); //不存在任何位为1