
C 语言过渡 C++
本笔记按”基础篇 → STL 篇 → 进阶篇 → C++11 篇”四部分整理,弥补 C 与 C++ 在语法、标准库、常用特性上的差异,作为刷题与竞赛入门的过渡资料。
一、基础篇
本节聚焦 C++ 相对 C 的核心语法变化:命名空间、IO 流、头文件、变量声明、bool、const、string、结构体、引用。
C++ 与 C 的核心差异速览
| 维度 | C 语言 | C++ |
|---|---|---|
| 输入输出 | scanf / printf | cin / cout(流式) |
| 头文件 | <stdio.h> | <iostream>(去 .h、加 c 前缀) |
| 变量声明 | 必须出现在语句块开头 | 任意位置(C++17 起更宽松) |
| 布尔类型 | 用 0/1 模拟 | 原生 bool,值为 true / false |
| 常量 | #define / enum | const / constexpr |
| 字符串 | char[] + 字符串函数 | 原生 string 类 |
| 结构体 | 必须写 struct stu a; | 可省略 struct,直接 stu a; |
| 引用 | 无(只能传指针) | 引用 &(语法糖,本质是指针) |
| 函数默认值 | 无 | 支持参数默认值 |
| 函数重载 | 不支持 | 支持 |
命名空间 using namespace std
std是 C++ 标准库的命名空间,cin/cout/string等都在std里。
两种写法:
using namespace std;—— 一次性把std全部展开(偷懒,小项目/刷题常用)std::cin/std::cout—— 每次显式指定(正式项目推荐,避免命名冲突)
#include <iostream>
using namespace std;
int main() { int n; cin >> n; cout << "wohaoshuai" << n << endl;
return 0;}#include <iostream>
int main() { int n; std::cin >> n; std::cout << "wohaoshuai" << n << std::endl;
return 0;}注意:
endl等价于'\n' + flush(),频繁使用会降低 IO 性能。刷题数据量大时,可改为'\n'。
cin 和 cout
运行速度
注意:
cin/cout默认会与 C 标准库scanf/printf同步,且绑定到cin.tie(nullptr),因此比scanf/printf慢。数据量大时建议关闭同步。
关闭同步提速(刷题常用):
ios::sync_with_stdio(false);cin.tie(nullptr);使用方式:>> 读入、<< 输出、配合 endl 或 '\n' 换行。
头文件
C++ 标准库头文件去掉
.h,C 语言风格头文件加c前缀(stdio.h→cstdio),这样所有符号都在std命名空间里。
| C 风格 | C++ 风格 |
|---|---|
<stdio.h> | <cstdio> |
<string.h> | <cstring> |
<math.h> | <cmath> |
<stdlib.h> | <cstdlib> |
<ctype.h> | <cctype> |
#include <cstring>#include <cmath>变量声明
C99 之后 C 语言也允许在
for循环里定义循环变量,但 C++ 从一开始就支持——这在 C89 时代的 C 里是违法的。
#include <iostream>
int main() { for (int i = 0; i < 10; i++) { // 循环体,i 作用域仅限 for 块内 } // 这里使用 i 会编译报错 return 0;}bool 变量
bool是 C++ 原生类型,只有两个值:true/false。任何非 0 值 隐式转换为true,0转换为false。
#include <iostream>
using namespace std;
int main() { bool flag = true; bool flag2 = -1; bool flag3 = 0;
cout << flag << " " << flag2 << " " << flag3 << " " << endl; // 1 1 0
return 0;}注意:
cout输出bool会显示0/1,想看true/false需cout << boolalpha << flag;。
const 定义常量
const比#define更安全(有类型、参与编译检查),比enum更通用(任何类型都可)。
#include <iostream>
using namespace std;
int main() { const int MAX = 100;
cout << MAX << endl;
return 0;}string 类
C++ 的
string是对char[]的封装,自动管理内存,提供拼接、查找、截取等操作,比 C 的字符串函数安全得多。
#include <iostream>
using namespace std;
int main() { // 定义 string s = "hello"; string s2 = " world";
// 拼接 string s3 = s + s2; cout << s3 << endl; // hello world
// 输入输出 cin >> s; cout << s << endl;
// getline, 让带有空格的输入能被读取 getline(cin, s);
// 处理 // s.length() 获取字符串长度 cout << s.length << endl;
// s.substr(n, m) 从下标 n 开始,取 m 长度的字串 cout << s3.substr(0, 2) << endl; // he
return 0;}常用方法速览:
| 方法 | 功能 |
|---|---|
s.length() / s.size() | 获取长度 |
s1 + s2 | 拼接 |
s1 == s2 | 比较 |
s.substr(pos, len) | 截取子串 |
s.find(str) | 查找子串位置,未找到返回 string::npos |
s.replace(pos, len, str) | 替换 |
s.insert(pos, str) | 插入 |
s.erase(pos, len) | 删除 |
注意:刷题时输入含空格的整行用
getline(cin, s);cin >> s遇到空格就停。
结构体
C++ 中可省略
struct关键字直接使用类型名,结构体里也能写函数(与类几乎等价,区别在默认访问权限)。
#include <iostream>using namespace std;
struct stu { string name; int age;};
int main() { stu a[10]; // 省略 struct
return 0;}引用 & 和 取地址 &
C++ 的
&和 C 语言的&是两个完全不同的符号:C++ 中&在类型后是引用声明(语法糖),在变量前是取地址。
| 用法 | 含义 | 示例 |
|---|---|---|
int& r = a; | 声明引用(r 是 a 的别名) | 函数参数传递、避免拷贝 |
&a | 取变量 a 的地址 | int* p = &a; |
a && b | 逻辑与(与 C 相同) | if (a && b) {...} |
引用的本质:编译器内部实现为常量指针(int* const p = &a;),引用必须在声明时初始化、不能重新指向其他变量。
#include <iostream>using namespace std;
// 形参为引用 → 函数内修改会反映到调用方void c(int& a) { a++;}
int main() { int a = 4;
c(a);
cout << a << endl; // 5
return 0;}引用 vs 指针:引用更安全(无空引用、不可重绑),语法更简洁;指针更灵活(可空、可改、可算术)。优先用引用。
二、STL 篇
STL(Standard Template Library)是 C++ 的标准模板库,核心是容器 + 迭代器 + 算法。刷题 90% 的场景都依赖它。
容器分类总览
graph LR STL[STL 容器] --> SEQ[顺序容器] STL --> ASSOC[关联容器] STL --> UNORD[无序容器] SEQ --> V[vector] SEQ --> DEQ[deque] SEQ --> L[list] ASSOC --> S[set] ASSOC --> M[map] ASSOC --> MS[multiset] ASSOC --> MM[multimap] UNORD --> US[unordered_set] UNORD --> UM[unordered_map]
| 容器 | 底层 | 特点 | 时间复杂度 |
|---|---|---|---|
vector | 动态数组 | 随机访问 O(1),尾部插入 O(1) | 随机访问最优 |
deque | 分段数组 | 头尾插入 O(1) | 双端队列 |
list | 双向链表 | 任意位置插入 O(1),无随机访问 | 频繁插入 |
set / map | 红黑树 | 自动排序,查找 O(log n) | 有序场景 |
unordered_set / unordered_map | 哈希表 | 查找 O(1) 平均 | 不需排序的最快查找 |
vector
动态数组,默认容器,刷题首选。
size()动态变化,超出容量时自动 2 倍扩容。
#include <iostream>#include <vector> // 头文件using namespace std;
int main() { // 创建数组 vector<int> a; // 不分配空间 vector<int> b(10); // 分配 10 个空间,元素值默认为 0 vector<int> c(10, 2); // 分配 10 个空间,每个初始化为 2
// 分配数组大小 a.resize(10);
// .size() 获取长度 cout << a.size() << endl; // 10
// 赋值 for (int i = 0; i < a.size(); i++) { a[i] = i; cout << a[i] << " "; } // 0 1 2 3 4 5 6 7 8 9
// 末尾添加新数据 a.push_back(11); for (int i = 0; i < a.size(); i++) { cout << a[i] << " "; } // 0 1 2 3 4 5 6 7 8 9 11
// 迭代器 for (auto p = a.begin(); p != a.end(); p++) { cout << *p << " "; } // 0 1 2 3 4 5 6 7 8 9 11
return 0;}常用方法:
| 方法 | 功能 |
|---|---|
v.push_back(x) | 尾部插入 |
v.pop_back() | 尾部删除 |
v.size() / v.empty() | 长度 / 是否为空 |
v.resize(n) | 调整大小 |
v.clear() | 清空 |
v.front() / v.back() | 访问首尾元素 |
v.begin() / v.end() | 迭代器 |
set
set是集合,元素互异且自动从小到大排序。底层是红黑树,插入/查找/删除都是 O(log n)。
#include <iostream>#include <set> // 头文件using namespace std;
int main() { // 创建集合 set<int> s; // 和 vector 类似,因为集合元素互异,所以不能通过参数初始化
// 插入 s.insert(1); s.insert(2); s.insert(3);
// 遍历——迭代器 for (auto p = s.begin(); p != s.end(); p++) { cout << *p << " "; } // 1 2 3
// 查找 s.find(data),寻找 data 的地址,返回值是一个指针 cout << (s.find(2) != s.end()) << endl; // 1 表示地址不同,已经找到 cout << (s.find(4) != s.end()) << endl; // 0 地址指向数组后一位空间,没找到
// 删除 s.erase(1); // 删除元素 1 cout << (s.find(1) != s.end()) << endl; // 0 未找到,1 已删除
// 获取长度 cout << s.size() << endl; return 0;}注意:
s.erase(1)中的1是值(会先查找再删除);如果传迭代器it,则删除该位置元素。
map(键值对)
map是键值对集合,按键自动从小到大排序(multimap允许键重复)。
#include <iostream>#include <map> // 头文件using namespace std;
int main() { // 创建键值对 map<string, int> m;
// 添加 m["hello"] = 2; m["world"] = 3;
cout << "hello : " << m["hello"] << endl; // hello : 2
// 迭代器 for (auto p = m.begin(); p != m.end(); p++) { cout << p->first << ":" << p->second << " "; } /* hello:2 world:3 */
// 获取长度 cout << m.size() << endl;
return 0;}注意:
m["key"]即使key不存在也会插入默认值,可能掩盖逻辑错误。判断存在性用m.find(key) != m.end()或m.count(key) > 0。
pair(键值对简述)
pair<T1, T2>把两个值绑在一起,常用于map的迭代器(p->first是键,p->second是值)。
pair<string, int> p = {"age", 18};cout << p.first << "=" << p.second; // age=18stack(栈)
stack是后进先出(LIFO)的容器适配器,底层默认用deque实现。只允许访问栈顶。
#include <iostream>#include <stack>using namespace std;
int main() { stack<int> s;
// 压栈 s.push(1); s.push(2); s.push(3);
// 访问栈顶 cout << s.top() << endl; // 3
// 出栈 s.pop(); cout << s.top() << endl; // 2
// 获取长度 cout << s.size() << endl; // 2
// 是否为空 cout << s.empty() << endl; // 0 (false)
return 0;}常用方法:push(压栈)→ top(访问栈顶)→ pop(出栈)→ size / empty。
注意:
pop只删元素不返回值,必须先用top()拿到值再pop()。
queue(队列)
queue是先进先出(FIFO)的容器适配器。BFS、层次遍历、滑动窗口常用。
#include <iostream>#include <queue>using namespace std;
int main() { queue<int> q;
// 入队 q.push(1); q.push(2); q.push(3);
// 访问队首 cout << q.front() << endl; // 1
// 访问队尾 cout << q.back() << endl; // 3
// 出队 q.pop(); cout << q.front() << endl; // 2
// 获取长度 cout << q.size() << endl; // 2
return 0;}常用方法:push(入队)→ front(队首) / back(队尾)→ pop(出队)→ size / empty。
deque(双端队列)
头尾都能 O(1) 插入/删除,支持随机访问(
dq[i])。queue和stack的功能它都覆盖,但常数略大。
#include <iostream>#include <deque>using namespace std;
int main() { deque<int> dq = {1, 2, 3}; dq.push_front(0); // 头部插入 dq.push_back(4); // 尾部插入 cout << dq[1]; // 1(随机访问) return 0;}unordered_map 和 unordered_set
这两个就是不会排序的
map(键值对)和set(集合),底层是哈希表。如果刷题时map/set超时,换成它们通常能快一档。
#include <iostream>#include <unordered_map>using namespace std;
int main() { unordered_map<string, int> um; um["a"] = 1; um["b"] = 2; cout << um["a"]; // 1 return 0;}注意:哈希表最坏复杂度 O(n),且无序;如需有序遍历、有序集合,请用
map/set。
迭代器分类
| 类别 | 支持的操作 | 典型容器 |
|---|---|---|
| 输入迭代器 | 只读、++ | istream_iterator |
| 前向迭代器 | 读写、++ | forward_list |
| 双向迭代器 | 读写、++ / -- | list / set / map |
| 随机访问迭代器 | 读写、++ / -- / +n / -n / [] | vector / deque |
注意:STL 算法(
sort、binary_search等)依赖迭代器类别,sort不能用于list/set,这些容器自带排序或list::sort()。
三、进阶篇
本节收录
bitset、sort、二分查找、字符处理等刷题常用工具。
位运算 bitset
bitset类似一个固定长度的二进制位数组。位数在编译期必须确定(下标b[0]是低位,b[size-1]是高位),所以直接输出整个bitset的方向与b[i]单个访问方向相反。
#include <iostream>#include <bitset>using namespace std;
int main() { // 初始化 bitset<5> b; // 5 表示 5 个二进制位,初始化为 0,00000 bitset<5> c(3); // 十进制转二进制,输出 c 的结果为 00011 bitset<5> d("101"); // 填入字符串,长度不够高位补 0,输出 d 的结果为 00101 string s = "01010011"; bitset<5> e(s, 1, 5); // 从字符串的索引 1 开始取 5 个字符 10100,输出 e 的结果为 10100 bitset<6> f("10011", 1); // 从字符串的索引 0 开始取 1 个字符高位补零,输出 f 的结果为 000001
cout << b << endl; // 00000 cout << c << endl; // 00011 cout << d << endl; // 00101 cout << e << endl; // 10100 cout << f << endl; // 00011
// 遍历 for (int i = 0; i < d.size(); i++) { cout << d[i] << " "; }
// 处理 cout << "是否有 1:" << d.any() << endl; cout << "是否不存在 1:" << d.none() << endl; cout << "1 的个数:" << d.count() << endl; cout << "d 中元素个数:" << d.size() << endl; cout << "下标为 i 的元素是不是 1:" << d.test(1) << endl;
d.set(3); // 把下标为 i 处设置为 1
// 归零 b.reset(); // 所有位归零 d.reset(2); // 第 i 位归零
// 取反 d.flip(); // 所有位取反 d.flip(2); // 第 i 位取反
// 转换类型 cout << "转换为 unsigned long 类型:" << d.to_ulong() << endl; cout << "转换为 string 类型:" << d.to_string() << endl;
return 0;}常用方法:
| 方法 | 功能 |
|---|---|
b.any() / b.none() | 是否存在 / 不存在 1 |
b.count() | 1 的个数 |
b.set(i) / b.reset(i) | 置 1 / 置 0 |
b.flip() | 按位取反 |
b.test(i) | 第 i 位是否为 1 |
b.to_ulong() / b.to_string() | 转 unsigned long / string |
sort 函数
sort对区间[first, last)进行排序,默认升序。vector容器用v.begin()表示头、v.end()表示尾;原生数组int arr[]用arr表示首地址、arr + n表示尾。
#include <iostream>#include <algorithm>#include <vector>using namespace std;int main() { vector<int> m(10); for (int i = 0; i < m.size(); i++) { m[i] = i; }
m.push_back(-1); // 排序 sort(m.begin(), m.end());
for (int i = 0; i < m.size(); i++) cout << m[i] << " "; // -1 0 1 2 3 4 5 6 7 8 9 return 0;}使用 sort 自定义 cmp 函数
cmp(x, y)返回true表示x排在y前面。返回值必须用严格>或<,不能用>=或<=(否则相等情况会导致排序不稳定 / 未定义行为)。
#include <iostream>#include <algorithm>#include <vector>using namespace std;
bool cmp(int x, int y) { return x > y; // 降序}int main() { vector<int> v; for (int i = 1; i <= 10; i++) { v.push_back(11 - i); // 10, 9, 8, ..., 1 }
for (auto p = v.begin(); p != v.end(); p++) cout << *p << " ";
cout << endl;
// 排序 sort(v.begin(), v.end(), cmp); // 原理:返回值为真,x 放 y 前面;为假,x 放 y 后面
for (auto p = v.begin(); p != v.end(); p++) cout << *p << " "; // 10 9 8 7 6 5 4 3 2 1 return 0;}结构体多关键字排序:
#include <iostream>#include <algorithm>#include <vector>using namespace std;
struct stu { string name; int age;};
bool cmp(stu a, stu b) { if (a.age != b.age) { return a.age < b.age; // 年龄小的在前 } else { return a.name < b.name; // 同龄按名字字典序 }}
int main() { stu s[3]; for (int i = 0; i < 3; i++) { cin >> s[i].name >> s[i].age; } sort(s, s + 3, cmp); for (int i = 0; i < 3; i++) { cout << s[i].name << " " << s[i].age << endl; } return 0;}stable_sort / partial_sort
| 函数 | 特点 |
|---|---|
sort | 不保证相等元素原顺序(不稳定) |
stable_sort | 稳定排序(相等元素保持原顺序),略慢 |
partial_sort(beg, mid, end) | 只排序到 mid 位置(取前 k 小),O(n log k) |
二分查找 lower_bound / upper_bound
前提:区间已排序。返回值是迭代器(或指针),不是下标。
| 函数 | 含义 |
|---|---|
lower_bound(beg, end, val) | 第一个 >= val 的位置 |
upper_bound(beg, end, val) | 第一个 > val 的位置 |
binary_search(beg, end, val) | 是否存在 val(返回 bool) |
#include <algorithm>vector<int> v = {1, 2, 2, 3, 4};auto it = lower_bound(v.begin(), v.end(), 2); // 指向第一个 2auto it2 = upper_bound(v.begin(), v.end(), 2); // 指向 3cctype 头文件的函数
用于单个字符的判断与转换,常配合
string遍历使用。
| 函数 | 功能 |
|---|---|
isalpha(c) | 是否字母 |
islower(c) / isupper(c) | 是否小写 / 大写字母 |
isalnum(c) | 是否字母或数字 |
isspace(c) | 是否空白( / \t / \r / \n) |
isdigit(c) | 是否数字 |
tolower(c) | 转换为小写字母 |
toupper(c) | 转换为大写字母 |
四、C++11 篇
本节收录 C++11 起加入的现代语法:
auto、范围 for、to_string、stoi/stod、lambda、智能指针、nullptr。auto、to_string、stoi、stof、unordered_map、unordered_set都是 C++11 的标志性特性。
auto 声明
auto让编译器根据初始值推断变量类型,代码更简洁,尤其配合长类型名(如迭代器)。
基础用法:
auto x = 100; // intauto y = 1.5; // doubleauto s = "hello"; // const char*迭代器场景(C++11 之前要写很长):
vector<int> v = {1, 2, 3};// 之前:for (vector<int>::iterator it = v.begin(); it != v.end(); ++it)for (auto it = v.begin(); it != v.end(); ++it) cout << *it;注意:
auto会丢掉顶层const和引用。如果想保留,用const auto&(遍历时避免拷贝)。
基于范围的 for 循环
直接遍历容器或数组的每个元素,不需要下标。
#include <iostream>#include <vector>using namespace std;
int main() { int a[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; vector<int> v = {1, 2, 3, 4, 5};
// 输出数组中的每一个元素的值(不能改变元素的数值) for (int i : a) cout << i << " ";
cout << endl;
// 将数组中每一个元素都乘以 2,只有在引用的时候才能改变元素的值 for (int& i : a) i *= 2;
// 所有的容器,配合 auto,都可以使用这种方式来循环 for (auto i : v) cout << i << " ";
return 0;}注意:默认是拷贝遍历,原容器不变;要修改元素必须用
auto&/int&引用。
to_string
将数字转换为字符串,常用于拼接输出。
头文件:#include <string>
#include <iostream>#include <string>using namespace std;
int main() { string s = to_string(123); string s2 = to_string(3.14);
cout << s << endl; // 123 cout << s2 << endl; // 3.140000 return 0;}stoi 和 stod
| 函数 | 功能 |
|---|---|
stoi(s) | 字符串 → int |
stol(s) / stoll(s) | 字符串 → long / long long |
stoul(s) / stoull(s) | 字符串 → unsigned long / unsigned long long |
stof(s) | 字符串 → float |
stod(s) | 字符串 → double |
stold(s) | 字符串 → long double |
#include <iostream>#include <string>using namespace std;
int main() { int a = stoi("123"); double b = stod("123.34");
cout << a - 1 << endl; // 122 cout << b - 1 << endl; // 122.34 return 0;}注意:字符串非数字前缀会抛
std::invalid_argument异常;数字越界抛std::out_of_range。
lambda 表达式
lambda 是匿名函数,可内联写在调用处,常用于
sort/for_each等需要传函数对象的场景。
语法:[捕获列表](参数) -> 返回值 { 函数体 }
#include <algorithm>#include <vector>using namespace std;
int main() { vector<int> v = {3, 1, 4, 1, 5, 9, 2, 6}; // 降序排序:lambda 替代独立 cmp 函数 sort(v.begin(), v.end(), [](int a, int b) { return a > b; }); return 0;}常用捕获:
| 写法 | 含义 |
|---|---|
[] | 不捕获任何变量 |
[=] | 按值捕获所有外部变量 |
[&] | 按引用捕获所有外部变量 |
[x, &y] | x 按值、y 按引用 |
智能指针(简述)
补充知识:C++11 起标准库提供自动管理堆内存的智能指针,避免
new/delete配对失误导致内存泄漏。
| 智能指针 | 特点 |
|---|---|
unique_ptr<T> | 独占所有权,不可复制,只能 move |
shared_ptr<T> | 共享所有权,引用计数,最后一个销毁时释放 |
weak_ptr<T> | 不增加引用计数,配合 shared_ptr 解决循环引用 |
#include <memory>unique_ptr<int> p = make_unique<int>(10);shared_ptr<int> sp = make_shared<int>(20);nullptr
nullptr是 C++11 引入的空指针常量,类型严格为std::nullptr_t,替代 C 风格的NULL(NULL实际是0,会和整数重载冲突)。
int* p = nullptr; // 推荐int* q = NULL; // 不推荐,NULL == 0知识小结
| 要点 | 说明 | 重要度 |
|---|---|---|
| 命名空间 | using namespace std; 仅刷题用,项目慎用 | ★★★ |
| cin/cout 提速 | ios::sync_with_stdio(false); cin.tie(nullptr); | ★★★★ |
| 头文件 | C 风格去 .h 加 c 前缀 | ★★★ |
| bool | 原生类型,非 0 即 true | ★★ |
| string | 自动管理内存,含 substr / find / length | ★★★★ |
| 结构体 | C++ 可省略 struct 关键字 | ★★ |
引用 & vs 取地址 & | 类型后是引用,变量前是取地址 | ★★★★★ |
| vector | 顺序容器首选,随机访问 O(1) | ★★★★★ |
| set / map | 有序容器,红黑树,O(log n) | ★★★★★ |
| stack / queue | 容器适配器,仅暴露受限接口 | ★★★★ |
| unordered_map / set | 哈希表,平均 O(1),最坏 O(n) | ★★★★ |
| 迭代器 | begin() / end() 是半开区间 [begin, end) | ★★★★ |
| bitset | 编译期定长位数组,索引 0 是低位 | ★★★ |
| sort 的 cmp | 必须用严格 > / <,不能用 >= / <= | ★★★★★ |
| auto | 推断类型,丢掉 const / 引用 | ★★★★ |
| 范围 for | for (auto& x : v) 修改、auto x 拷贝 | ★★★★ |
| stoi / stod | 字符串转数字,越界抛异常 | ★★★ |
| lambda | [捕获](参数){...},常作 sort 第三参数 | ★★★ |
| nullptr | 替代 NULL,类型安全 | ★★★ |
补充 整型的选择
🧮 C++ 整型速查表(刷题专用)
| 类型 | 字节 | 二进制范围 | 十进制约等于 | 适用情况 |
|---|---|---|---|---|
int | 4 | ~ | ≈ ±2.147×10⁹ | 单值 ≤ 2×10⁹ |
unsigned int | 4 | ~ | ≈ 0 ~ 4.29×10⁹ | 只用正数且 ≤ 4e9 |
long long | 8 | ~ | ≈ ±9.22×10¹⁸ | 单值 ≤ 9×10¹⁸ |
unsigned long long | 8 | ~ | ≈ 1.84×10¹⁹ | 超大正数(极少用) |
🔑 常见次方对照
| 幂次 | 十进制近似 | 对应类型上限 |
|---|---|---|
| 1,000,000,000 | < int max | |
| 1,000,000,000,000,000,000 | < long long max | |
| 2,147,483,648 | 比 int max 大 1 → 用 long long | |
| 2,147,483,647 | int 最大值 | |
| 9,223,372,036,854,775,808 | 比 long long max 大 1 → 用 unsigned long long | |
| 9,223,372,036,854,775,807 | long long 最大值 |
⚠️ 避坑规则(必看)
- 单值:看到 →
int;看到 →long long。 - 求和:若数组长度 × 单值上限 > 当前类型范围,总和变量要升一级。
- 乘法中间值:
int a=1e6, b=1e6; long long c = 1LL * a * b;—— 乘1LL强制提升。 - 不确定时:一律用
long long(除非二维数组过大,内存不够才精细算)。 - 不要用
long:不同平台长度不一(Windows 4 字节,Linux 8 字节),刷题统一用int和long long。
分享文章
生成精美分享图或复制链接,与更多人分享本文。
继续阅读
换条路线
从其他文章中稳定抽取
最后更新于 ,距今已过 10 天
部分内容可能已过时
评论