C++上机基础
C/C++ 的 main 函数必须是 int 类型。程序正常结束时的返回值必须是 0。
ceil(num)//向上取整
floor(num)//向下取整
INT_MAX和INT_MIN是C/C++中的常量,分别表示最大/最小整数,头文件是limits.h。
while(cin>>n){ // cin>>n 成功时返回true,失败时返回false
a.push_back(n);
}
cin >> n 在以下情况会返回 false(结束循环):
-
遇到 EOF(文件结束)
-
输入类型不匹配(比如输入字母而n
while(cin >> n && n != 0){ // 遇到0也结束
a.push_back(n);
}
// 不需要 pop_back(),因为0没存进去
读取字符串时,cin遇到空格和换行时停止读取,
getline :
用 getline 函数来读取含空格的字符串 s,遇换行停止
| 特性 | 说明 |
|---|---|
| 结束标志 | 遇到 换行符 \n 停止读取 |
| 换行符处理 | 从缓冲区提取并丢弃,不存入字符串 |
| 读取内容 | 换行符之前的所有字符(包括空格) |
ASCII:
1.3、字符编码:
- 数字'0'-'9': 48-57
- 大写'A'-'Z': 65-90
- 小写'a'-'z': 97-122
- 符号:空格(32)、@(64)、!(33)等。
特点:
- 大小写字母编码相差32
- 数字、字母编码连续排列

字符串
英文字母共有26个
库函数判断字母、数字等
isdigit(s[i]) //判断是否是数字
islower(s[i]) //判断是否是小写字母
isupper(s[i])//判断是否是大写字母
isalpha(s[i])//判断是否为字母
islower/isupper判断char为小/大写字母
返回值: bool
isalnum 函数:
判断是否为大、小写英文字母和数字,是返回 0,不是返回一个非零的数
if (isalnum(s[i]) != 0) ans++;
if (s[i] >= 'a' && s[i] <= 'z') { //小写字母
ans++;
}
if (s[i] >= 'A' && s[i] <= 'Z') { //大写字母
ans++;
}
if (s[i] >= '0' && s[i] <= '9') { //数字
ans++;
}
if (s[i] != ' ' && s[i] != '\n') {
ans++;
}
char与int转换
-'0'或者-48(char → int)把数字字符转换成对应的数值
+'0'或者+48(int → char)把数值转换成对应的数字字符
int x = ch - '0'; // 字符 → 数字
char ch = x + '0'; // 数字 → 字符
循环移位
凯撒密码 / 循环移位公式:
新字符 = (原字符 - 基准 + 偏移) % 范围 + 基准
其中:
- 小写字母:基准='a',范围=26
- 大写字母:基准='A',范围=26
- 数字:基准='0',范围=10
| 场景 | 公式 |
|---|---|
| 小写循环移位 | (s - 'a' + n) % 26 + 'a' |
| 大写循环移位 | (s - 'A' + n) % 26 + 'A' |
| 数字循环移位 | (s - '0' + n) % 10 + '0' |
char大小写转换
-
小写转大写:ch- 32、ch +'A' - 'a'、ch=toupper(ch)
-
大写转小写:ch+32、ch - 'A' + 'a'、ch=tolower(ch)
(1)操作对象单个字符char、(2)'A'-'a' = -32
s=toupper(s);
if(s>'a'&&s<'z'){
s-=32;
// s += 'A' - 'a'; 即 s -= ('a' - 'A')
}
cin >> c; // 读取 "Hello"
getchar(); // 吃掉缓冲区里的 '\n'(那个回车)
getline(cin, s); // 现在能正确读取 "World I am LiHua"
s.find(str):
在字符串 s 中查找子串 str,返回第一次出现的位置。
| 情况 | 返回值 | 说明 |
|---|---|---|
| 找到 | 位置索引(0 ~ s.length()-1) |
第一次出现的位置 |
| 未找到 | string::npos |
特殊常量,通常等于 -1 或 184467... |
二、构造函数与赋值
| 操作 | 代码 | 结果 |
|---|---|---|
| 构造空串 | string s; |
"" |
| 构造n个c | string s(n, 'c'); |
"ccc...c" |
| 子串构造 | string s(str, pos, len); |
从str截取 |
| 赋值 | s = "abc"; |
"abc" |
| 交换 | s1.swap(s2); |
交换内容 |
三、访问元素
| 操作 | 代码 | 说明 |
|---|---|---|
| 下标访问 | s[i] 或 s.at(i) |
at() 检查越界 |
| 首字符 | s.front() |
等价 s[0] |
| 尾字符 | s.back() |
等价 s[s.size()-1] |
四、容量相关
| 操作 | 代码 | 说明 |
|---|---|---|
| 长度 | s.size() 或 s.length() |
等价 |
| 是否为空 | s.empty() |
布尔值 |
| 清空 | s.clear(); |
变为空串 |
| 预留空间 | s.reserve(n); |
避免频繁扩容 |
reverse(头, 尾):左闭右开,原地翻转
| 操作 | 代码 |
|---|---|
| 全反转 | reverse(s.begin(), s.end()) |
| 前k个反转 | reverse(s.begin(), s.begin() + k) |
| 后k个反转 | reverse(s.end() - k, s.end()) |
| 中间反转 | reverse(s.begin() + l, s.begin() + r + 1) |
五、修改操作
| 功能 | 代码 | 说明 |
|---|---|---|
| 追加 | s += str; 或 s.append(str); |
尾部追加 |
| 插入 | s.insert(pos,len,str); |
在pos位置插入 |
| 删除 | s.erase(pos, len); |
删除子串 |
| 替换 | s.replace(pos, len, str); |
替换子串 |
| 截取 | s.substr(pos, len); |
返回子串(原串不变) |
| 压入字符 | s.push_back('c'); |
尾部加单个字符 |
| 弹出字符 | s.pop_back(); |
删除最后一个 |
六、查找操作
| 函数 | 功能 | 未找到返回 |
|---|---|---|
s.find(str, pos) |
正向查找 | string::npos |
七、比较操作
| 操作 | 代码 | 说明 |
|---|---|---|
| 相等 | s1 == s2 |
布尔值 |
| 字典序 | s1 < s2 |
按ASCII比较 |
| 比较函数 | s1.compare(s2) |
返回0(相等)/负数/正数 |
八、数值转换(C++11)
| 功能 | 代码 | 说明 |
|---|---|---|
| 字符串→整数 | stoi(s) |
返回 int |
| 字符串→长整数 | stoll(s) |
返回 long long |
| 字符串→浮点 | stod(s) |
返回 double |
| 数值→字符串 | to_string(n) |
各种数值类型 |
九、遍历方式
string s = "Hello";
// 方式1:下标
for (int i = 0; i < s.size(); i++)
cout << s[i];
// 方式2:范围for(只读)
for (char c : s)
cout << c;
// 方式3:引用修改
for (char &c : s)
c = toupper(c);
// 方式4:迭代器
for (auto it = s.begin(); it != s.end(); it++)
cout << *it;
十、常用算法(需 <algorithm>)
// 反转
reverse(s.begin(), s.end());
// 排序
sort(s.begin(), s.end());
// 去重(先sort)
s.erase(unique(s.begin(), s.end()), s.end());
// 转大写/小写
transform(s.begin(), s.end(), s.begin(), ::toupper);
transform(s.begin(), s.end(), s.begin(), ::tolower);
// 两种写法展开后
for(cin >> T; T > 0; T--) { ... }
// 等价于:
cin >> T;
while(T > 0) {
...
T--; // 循环体结束后执行,返回值被丢弃
}
// 和
for(cin >> T; T > 0; --T) { ... }
// 等价于:
cin >> T;
while(T > 0) {
...
--T; // 同样,返回值被丢弃
}
char s[INT_MAX];string str;
strcpy(s, str.c_str());
| 部分 | 含义 |
|---|---|
str.c_str() |
将 C++ string 转换为 C 风格的 const char* |
strcpy(s, ...) |
将源字符串拷贝到目标字符数组 s |
| 整体 | 把 string 的内容复制到 char 数组中 |
sscanf 字符串解析:
-
格式固定的数据提取、快速解析数字、日期等、处理 C 风格字符串
sscanf(源字符串, 格式模板, &变量1, &变量2, ...);
↓
返回值 = 成功匹配的变量个数
sprintf:
将格式化的数据写入字符串,与 printf 类似,但输出目标是字符串而非屏幕。
各平台 EOF 输入方法
| 操作系统 | 快捷键 |
|---|---|
| Windows | Ctrl + Z,然后按 回车 |
| Linux / Mac | Ctrl + D |
| 在线评测系统 | 自动处理 |
各类型占符
一、整型
| 类型 | 占位(字节) | 占位(位) | 范围 | 说明 |
|---|---|---|---|---|
char |
1 | 8 | −27 ~ 27−1 (-128 ~ 127) | 最小整数类型 |
unsigned char |
1 | 8 | 0 ~ 28−1 (0 ~ 255) | 无符号字节 |
short |
2 | 16 | −215 ~ 215−1 (-32768 ~ 32767) | 短整型 |
unsigned short |
2 | 16 | 0 ~ 216−1 (0 ~ 65535) | 无符号短整型 |
int |
4 | 32 | −231 ~ 231−1 (约 ±21.47亿) | 最常用 |
unsigned int |
4 | 32 | 0 ~ 232−1 (约 0 ~ 42.95亿) | 无符号整型 |
long |
4 或 8 | 32 或 64 | Windows: −231 ~ 231−1 ;Linux64: −263 ~ 263−1 | 平台相关 |
unsigned long |
4 或 8 | 32 或 64 | 对应无符号版本 | 平台相关 |
long long |
8 | 64 | −263 ~ 263−1 (约 ±9.22×10¹⁸) | 大整数 |
unsigned long long |
8 | 64 | 0 ~ 264−1 (约 0 ~ 1.84×10¹⁹) | 无符号大整数 |
二、浮点型
| 类型 | 占位(字节) | 占位(位) | 有效数字 | 大致范围 | 说明 |
|---|---|---|---|---|---|
float |
4 | 32 | 6~7位 | ±2−126 ~ ±2128 (约 ±3.4×10³⁸) | 单精度 |
double |
8 | 64 | 15~16位 | ±2−1022 ~ ±21024 (约 ±1.8×10³⁰⁸) | 双精度,最常用 |
long double |
8, 12 或 16 | 64, 96 或 128 | 18~21位 | 平台相关,通常 ≥ double |
扩展精度 |
注:
long double在 x86 通常是 80 位(12字节),在 x64 可能是 128 位(16字节)
三、字符与布尔型
| 类型 | 占位(字节) | 占位(位) | 范围 | 说明 |
|---|---|---|---|---|
char |
1 | 8 | −27 ~ 27−1 或 0 ~ 28−1 | 字符/小整数 |
signed char |
1 | 8 | −27 ~ 27−1 | 有符号字符 |
unsigned char |
1 | 8 | 0 ~ 28−1 | 无符号字符 |
wchar_t |
2 或 4 | 16 或 32 | 宽字符 | Windows: 2字节;Linux: 4字节 |
char16_t |
2 | 16 | UTF-16 | C++11 |
char32_t |
4 | 32 | UTF-32 | C++11 |
bool |
1 | 8 | true 或 false |
实际存储 0 或 1 |
vector容器
一、增删改查
| 操作 | 代码 | 时间复杂度 |
|---|---|---|
| 尾部添加 | v.push_back(x) |
O(1) 均摊 |
| 尾部删除 | v.pop_back() |
O(1) |
| 插入 | v.insert(v.begin()+i, x) |
O(n) |
| 删除 | v.erase(v.begin()+i) |
O(n) |
| 清空 | v.clear() |
O(n) |
| 访问 | v[i] 或 v.at(i) |
O(1) |
二、 遍历方式
for (int i = 0; i < v.size(); i++) // 索引遍历
for (auto x : v) // 范围for(C++11)
三、属性
v.size(); // 元素个数
v.empty(); // 是否为空
v.resize(n); // 改变元素个数
vector默认构造为空,必须用resize()或构造参数分配空间后再访问
二维数组 同时改变行列
// 先调整行数
matrix.resize(newRows);
// 再调整每行的列数
for (auto& row : matrix) {
row.resize(newCols, 0); // 新增元素默认值为 0
}
四、二维vector
// 方式1:直接初始化
vector<vector<int>> a(m, vector<int>(n, 0)); // m行n列,初始化为0
// 方式2:动态添加
vector<vector<int>> ma;
for (int i = 0; i < m; i++) {
vector<int> row(n);
// ...填充row
a.push_back(row);
}
// 访问
a[i][j] = 10;
五、操作
#include <algorithm>
sort(v.begin(), v.end()); // 升序
reverse(v.begin(), v.end()); // 反转
find(v.begin(), v.end(), x); // 查找,返回迭代器
binary_search(v.begin(), v.end(), x); // 二分查找(需有序)
lower_bound(v.begin(), v.end(), x); // 第一个≥x的位置
upper_bound(v.begin(), v.end(), x); // 第一个>x的位置
数组
C++ 没有"全填充"语法,必须循环或使用 fill
memset 只能安全用于 0 和 -1(二进制全 0 或全 1)
memset(a, 0, sizeof(a)); // ✅ 正确,结果为 0或者写-1
算法逻辑混淆——组合 vs 排列
| 概念 | 特征 | 循环写法 |
|---|---|---|
| 组合(原代码误用) | 不重复、有序(递增) | i = ans[cur-1] + 1 |
| n元组(题目要求) | 可重复、独立选择 | i = 1 到 k |
更多推荐


所有评论(0)