string::size_type
string::size_type 是 string 专门用于“长度/下标”的类型,本质是无符号整数,通常等价于 size_t。
为什么不用 int
s.size()返回无符号类型,和int(有符号)比较会触发警告。int容量可能不够(常见 32 位),size_type会随平台自动适配。- 可移植性更好,避免平台差异带来的长度问题。
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 提供字符分类与转换函数,常见形式是:
- 判断类:
isalpha、isdigit、isspace、isalnum等。 - 转换类:
tolower、toupper。
这些函数返回非零表示条件成立,返回 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