C++ 笔记

789 字
4 分钟
C++ 笔记

一、基础语法#

指针#

指针(Pointer)是实际的内存地址;指针变量(Pointer Variable)是存储内存地址的变量。

void* pWide; // 泛型指针,可指向任意类型,但必须显式转换
int* p = nullptr; // 空指针

获取变量类型#

使用 <typeinfo> 中的 typeid,可读性转化需 <cxxabi.h>(不在 stdc++ 中):

auto type = typeid(p).name();
auto type_vr = abi::__cxa_demangle(type, nullptr, nullptr, nullptr);

尾置返回类型#

返回指向数组的指针:

auto func(int arr[][3], int n) -> int(*)[3] { return &arr[n]; }
int (*func1(int arr[][3], int n))[3] { return &arr[n]; }

Lambda 表达式#

类型必须为 auto,捕获列表:& 引用、= 值、&a 引用特定变量、a 值特定变量。

auto funcf(auto x) -> double { return x + 1; } // 普通函数
auto funcl = [](auto x) -> double { return x + 1; }; // Lambda

一元运算符#

sizeofalignof 是由字母组成的一元运算符,不是函数:

cout << sizeof num_a << ' ' << alignof num_a << endl;

位运算#

用掩码提取个位(判断奇偶):

if (num_a & 1) cout << "奇数" << endl;

程序入口#

int argc 表示命令行参数的个数,包括程序的名称;char** argv 表示命令行参数的内容,argv[0] 是程序名称。

int main(int argc, char** argv){}

把十六进制当成 float 赋值#

#include <bit>
float a = std::bit_cast<float>(0xcc678000); // (unsigned int)3429335040U
cout << a; // -60686336.0

二、循环写法#

范围循环(C++20 Ranges)#

for (auto i : std::views::iota(1, 1001)); // [1, 1000]
for (auto i : std::views::iota(1, 10000000) | std::views::stride(3)); // 步长为 3

递增循环,循环 n 次#

int i = 0;
while (i++ < n) cout << i << ' '; // 输出 1 2 3 ... n
for (int i = 1; i <= n; i++) cout << i << ' '; // 输出 1 2 3 ... n
for (int i = 0; i < n; i++) cout << i << ' '; // 输出 0 1 2 ... n-1

递减循环,循环 n 次#

i = n;
while (i --> 0) cout << i << ' '; // 实为 i--,输出 9 8 7 ... 0
i = n + 1;
while (--i) cout << i << ' '; // 输出 10 9 8 ... 1

三、vector 操作#

初始化#

vector<int> a(n, 0); // n 个 0
vector<int> a(src.begin(), src.end()); // 迭代器范围
vector a {1, 3, 2, 2, 5}; // 初始化列表(CTAD)
vector<int> a {1,3,2,2,5};

push_back vs emplace_back#

vector<pair<int, string>> v;
v.push_back(make_pair(1, "hello")); // 先创建 make_pair(1, "hello"),再拷贝/移动到 vector
v.emplace_back(1, "hello"); // 直接在 vector 内部构造 pair<int, string>
vector<vector<int>> res;
res.push_back({1,2,3});
res.emplace_back(vector<int>{1,2,3});

排序与去重#

ranges::sort(a);
// 传统写法
auto double_start = unique(a.begin(), a.end());
a.erase(double_start, a.end());
// Ranges 写法
auto [first, last] = ranges::unique(a);
a.erase(first, last);

四、竞赛 I/O 优化#

ios::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr);
  • sync_with_stdio(false):关闭 C++ 和 C 的流同步,提高效率
  • cin.tie(nullptr):解除 cin 和 cout 的绑定
  • cout.tie(nullptr):解除 cout 和 cin 的绑定(一般不需要)
  • 使用 '\n' 代替 endl,后者会刷新缓冲区,性能更差(交互题除外)

五、计时#

#include <chrono>
auto hrc = chrono::high_resolution_clock::now;
auto op = hrc();
// ... 执行代码 ...
auto ed = hrc();
chrono::duration<double, milli> elapsed = ed - op;
cout << "Time: " << elapsed.count() << " ms\n";

六、随机树生成#

mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
vector<int> generate_tree(int n) {
vector<int> parent(n + 1);
for (int i = 2; i <= n; i++) {
parent[i] = rng() % (i - 1) + 1; // 随机父节点 ∈ [1, i-1]
}
return parent;
}

mt19937 配合时间戳作为随机种子,对每个节点随机选取编号更小的节点作为父节点,保证生成合法的随机有根树。

文章分享

如果这篇文章对你有帮助,欢迎分享给更多人!

C++ 笔记
https://cialo.site/posts/cpp-notes/
作者
洛璃
发布于
2026-06-28
许可协议
CC BY-NC-SA 4.0
Profile Image of the Author
洛璃
初春的离去,晚樱的谢幕
公告
欢迎来到我的博客!这是一则示例公告。
音乐
封面

音乐

暂未播放

0:000:00
暂无歌词
分类
标签
站点统计
文章
34
分类
11
标签
123
总字数
140,689
运行时长
0
最后活动
0 天前
站点信息
构建平台
Local
博客版本
Firefly v6.13.5
文章许可
CC BY-NC-SA 4.0

文章目录