<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>C++ on 鹿鸣青野的blog</title><link>https://www.sylgalaxy.xyz/categories/c++/</link><description>Recent content in C++ on 鹿鸣青野的blog</description><generator>Hugo</generator><language>zh-cn</language><lastBuildDate>Tue, 13 Oct 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://www.sylgalaxy.xyz/categories/c++/index.xml" rel="self" type="application/rss+xml"/><item><title>Boost.Asio 回调机制初步窥探</title><link>https://www.sylgalaxy.xyz/posts/boost-note/</link><pubDate>Tue, 13 Oct 2026 00:00:00 +0000</pubDate><guid>https://www.sylgalaxy.xyz/posts/boost-note/</guid><description>&lt;blockquote&gt;
&lt;p&gt;验证 Boost.Asio 开发环境 + 理解异步回调与 Qt 信号槽的对应关系&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="一环境验证异步定时器"&gt;一、环境验证：异步定时器&lt;/h2&gt;
&lt;p&gt;Asio 是纯头文件库（Header-Only），不需要 &lt;code&gt;b2.exe&lt;/code&gt; 编译，配置包含目录后即可 &lt;code&gt;#include&lt;/code&gt; 使用。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;验证代码&lt;/strong&gt;：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-cpp" data-lang="cpp"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;#include&lt;/span&gt; &lt;span style="color:#75715e"&gt;&amp;lt;iostream&amp;gt;&lt;/span&gt;&lt;span style="color:#75715e"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;#include&lt;/span&gt; &lt;span style="color:#75715e"&gt;&amp;lt;boost/asio.hpp&amp;gt;&lt;/span&gt;&lt;span style="color:#75715e"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;main&lt;/span&gt;() {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; boost&lt;span style="color:#f92672"&gt;::&lt;/span&gt;asio&lt;span style="color:#f92672"&gt;::&lt;/span&gt;io_context io;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; boost&lt;span style="color:#f92672"&gt;::&lt;/span&gt;asio&lt;span style="color:#f92672"&gt;::&lt;/span&gt;steady_timer timer(io, std&lt;span style="color:#f92672"&gt;::&lt;/span&gt;chrono&lt;span style="color:#f92672"&gt;::&lt;/span&gt;seconds(&lt;span style="color:#ae81ff"&gt;3&lt;/span&gt;));
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; timer.async_wait([](&lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; boost&lt;span style="color:#f92672"&gt;::&lt;/span&gt;system&lt;span style="color:#f92672"&gt;::&lt;/span&gt;error_code&lt;span style="color:#f92672"&gt;&amp;amp;&lt;/span&gt; ec) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; (&lt;span style="color:#f92672"&gt;!&lt;/span&gt;ec) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; std&lt;span style="color:#f92672"&gt;::&lt;/span&gt;cout &lt;span style="color:#f92672"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;&amp;gt;&amp;gt;&amp;gt; 3s elapsed, async callback fired&amp;#34;&lt;/span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;&amp;lt;&lt;/span&gt; std&lt;span style="color:#f92672"&gt;::&lt;/span&gt;endl;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; });
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; std&lt;span style="color:#f92672"&gt;::&lt;/span&gt;cout &lt;span style="color:#f92672"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;--- main thread continues immediately ---&amp;#34;&lt;/span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;&amp;lt;&lt;/span&gt; std&lt;span style="color:#f92672"&gt;::&lt;/span&gt;endl;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; io.run();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;预期输出&lt;/strong&gt;（顺序证明异步非阻塞）：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;--- main thread continues immediately ---
（3 秒间隔）
&amp;gt;&amp;gt;&amp;gt; 3s elapsed, async callback fired
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;strong&gt;证明了三件事&lt;/strong&gt;：&lt;/p&gt;</description></item><item><title>C/C++ 内存布局、程序构建与静态库动态库</title><link>https://www.sylgalaxy.xyz/posts/cpp-memory-layout/</link><pubDate>Tue, 13 Oct 2026 00:00:00 +0000</pubDate><guid>https://www.sylgalaxy.xyz/posts/cpp-memory-layout/</guid><description>&lt;p&gt;从内存区域划分（&lt;code&gt;.text&lt;/code&gt; / &lt;code&gt;.rodata&lt;/code&gt; / &lt;code&gt;.data&lt;/code&gt; / &lt;code&gt;.bss&lt;/code&gt; / 栈 / 堆）讲到构建四阶段（预处理 → 编译 → 汇编 → 链接），再到静态库与动态库的创建、链接行为差异，末尾汇总易错点。&lt;/p&gt;
&lt;h2 id="一内存布局在构建阶段就确定"&gt;一、内存布局在构建阶段就确定&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;Determined at Build Time：&lt;code&gt;.text&lt;/code&gt; / &lt;code&gt;.rodata&lt;/code&gt; / &lt;code&gt;.data&lt;/code&gt; / &lt;code&gt;.bss&lt;/code&gt; 的内存布局、大小在编译链接构建阶段就确定，不是程序跑起来才决定。这几段都属于 &lt;strong&gt;static lifetime 静态生命周期&lt;/strong&gt;，由编译器自动管理分配与释放，程序员不能手动干预申请释放。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;按数据类型、生命周期和作用域，C/C++ 程序的内存通常划分为五大区域：&lt;strong&gt;代码区、全局/静态存储区、栈区、堆区、常量区&lt;/strong&gt;。其中代码区对应 &lt;code&gt;.text&lt;/code&gt;，常量区对应 &lt;code&gt;.rodata&lt;/code&gt;，全局/静态存储区对应 &lt;code&gt;.data&lt;/code&gt; 与 &lt;code&gt;.bss&lt;/code&gt;，栈区与堆区则在运行时分配。&lt;/p&gt;
&lt;h3 id="1-text-代码段文本段--代码区"&gt;1. &lt;code&gt;.text&lt;/code&gt; 代码段（文本段 / 代码区）&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;存储内容&lt;/strong&gt;：编译之后的机器指令（machine code），即写出的函数、&lt;code&gt;if&lt;/code&gt;/&lt;code&gt;for&lt;/code&gt; 循环、&lt;code&gt;main&lt;/code&gt; 函数等翻译成 CPU 能执行的指令。所有的函数定义、控制结构都会被转换成机器指令存放在这里。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;大小&lt;/strong&gt;：Fixed size，构建阶段确定大小。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;权限&lt;/strong&gt;：Read-only &lt;strong&gt;只读&lt;/strong&gt;，防止运行时篡改程序指令。这部分内存是共享的，在程序执行期间不会改变。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;生命周期&lt;/strong&gt;：静态生命周期，进程整个运行期间都存在，进程退出由操作系统回收。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;管理&lt;/strong&gt;：完全由编译器、链接器自动管理，程序员没有 API 手动分配释放本段内存。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;编译时，&lt;code&gt;main&lt;/code&gt;、&lt;code&gt;func&lt;/code&gt; 等函数的代码被转换成机器指令存放在可执行文件的代码段中（此时还在磁盘上的可执行文件里）；程序运行时，操作系统把这些指令加载到内存的代码段，CPU 再从内存的代码段中读取并执行。&lt;/p&gt;
&lt;h3 id="2-rodata-只读数据段常量区"&gt;2. &lt;code&gt;.rodata&lt;/code&gt; 只读数据段（常量区）&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;存储内容&lt;/strong&gt;：初始化后的常量，比如字符串字面量 &lt;code&gt;&amp;quot;hello world&amp;quot;&lt;/code&gt;、&lt;code&gt;const char *p = &amp;quot;abc&amp;quot;&lt;/code&gt; 这类常量字符串，以及全局 &lt;code&gt;const&lt;/code&gt; 常量。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;权限&lt;/strong&gt;：只读 Read-only，程序运行不能修改，写操作会触发段错误。这部分内存同样通常在程序执行期间不会改变。&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;区分：&lt;code&gt;const int a = 10;&lt;/code&gt; 声明在全局放 rodata；局部 &lt;code&gt;const&lt;/code&gt; 变量本质还是在栈上。&lt;/p&gt;</description></item><item><title>C++ namespace、const 与 constexpr 知识点总结</title><link>https://www.sylgalaxy.xyz/posts/cpp-namespace-const-constexpr/</link><pubDate>Tue, 13 Oct 2026 00:00:00 +0000</pubDate><guid>https://www.sylgalaxy.xyz/posts/cpp-namespace-const-constexpr/</guid><description>&lt;p&gt;命名空间、常量限定符与编译期常量三件套：语法、特点表、易混点（const 修饰指针的读法）、C++11/14/17/20 的演进，以及综合实战示例。&lt;/p&gt;
&lt;h2 id="1-namespace-命名空间"&gt;1. namespace 命名空间&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;namespace&lt;/code&gt;（命名空间）用于&lt;strong&gt;避免全局命名冲突&lt;/strong&gt;，把相关的类型、函数、变量组织在一起，形成逻辑上的&amp;quot;作用域边界&amp;quot;。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;核心要点&lt;/strong&gt;：命名空间本质上是给标识符加了一个&amp;quot;姓氏&amp;quot;，从而把不同的名字区分开。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id="11-基本声明与使用"&gt;1.1 基本声明与使用&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-cpp" data-lang="cpp"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;#include&lt;/span&gt; &lt;span style="color:#75715e"&gt;&amp;lt;iostream&amp;gt;&lt;/span&gt;&lt;span style="color:#75715e"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;namespace&lt;/span&gt; Math {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;double&lt;/span&gt; PI &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;3.141592653589793&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;add&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; a, &lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; b) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; a &lt;span style="color:#f92672"&gt;+&lt;/span&gt; b;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;main&lt;/span&gt;() {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 使用 &amp;#34;::&amp;#34; 作用域限定符访问命名空间中的成员
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; std&lt;span style="color:#f92672"&gt;::&lt;/span&gt;cout &lt;span style="color:#f92672"&gt;&amp;lt;&amp;lt;&lt;/span&gt; Math&lt;span style="color:#f92672"&gt;::&lt;/span&gt;PI &lt;span style="color:#f92672"&gt;&amp;lt;&amp;lt;&lt;/span&gt; std&lt;span style="color:#f92672"&gt;::&lt;/span&gt;endl; &lt;span style="color:#75715e"&gt;// 3.14159...
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; std&lt;span style="color:#f92672"&gt;::&lt;/span&gt;cout &lt;span style="color:#f92672"&gt;&amp;lt;&amp;lt;&lt;/span&gt; Math&lt;span style="color:#f92672"&gt;::&lt;/span&gt;add(&lt;span style="color:#ae81ff"&gt;3&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;4&lt;/span&gt;) &lt;span style="color:#f92672"&gt;&amp;lt;&amp;lt;&lt;/span&gt; std&lt;span style="color:#f92672"&gt;::&lt;/span&gt;endl; &lt;span style="color:#75715e"&gt;// 7
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="12-命名空间的特点"&gt;1.2 命名空间的特点&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;特点&lt;/th&gt;
&lt;th&gt;说明&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;可嵌套&lt;/td&gt;
&lt;td&gt;命名空间内部可以再定义命名空间&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;可累加&lt;/td&gt;
&lt;td&gt;同一作用域下多次声明同一命名空间会合并&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;可匿名&lt;/td&gt;
&lt;td&gt;匿名命名空间相当于&amp;quot;文件内 static&amp;quot;，仅本文件可见&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;可起别名&lt;/td&gt;
&lt;td&gt;&lt;code&gt;namespace M = Math;&lt;/code&gt; 简化访问&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id="13-嵌套命名空间"&gt;1.3 嵌套命名空间&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-cpp" data-lang="cpp"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;namespace&lt;/span&gt; Outer {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;namespace&lt;/span&gt; Inner {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;void&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;foo&lt;/span&gt;() { &lt;span style="color:#75715e"&gt;/* ... */&lt;/span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// C++17 起可以简写为：
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;namespace&lt;/span&gt; Outer&lt;span style="color:#f92672"&gt;::&lt;/span&gt;Inner {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;void&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;bar&lt;/span&gt;() { &lt;span style="color:#75715e"&gt;/* ... */&lt;/span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// 访问方式
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Outer&lt;span style="color:#f92672"&gt;::&lt;/span&gt;Inner&lt;span style="color:#f92672"&gt;::&lt;/span&gt;foo();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Outer&lt;span style="color:#f92672"&gt;::&lt;/span&gt;Inner&lt;span style="color:#f92672"&gt;::&lt;/span&gt;bar();
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="14-匿名命名空间"&gt;1.4 匿名命名空间&lt;/h3&gt;
&lt;p&gt;匿名命名空间中的成员只在&lt;strong&gt;当前翻译单元&lt;/strong&gt;（.cpp 文件）内可见，等价于 &lt;code&gt;static&lt;/code&gt; 全局变量/函数，用于隔离实现细节。&lt;/p&gt;</description></item><item><title>C++ 并发编程：互斥锁、条件变量与原子操作</title><link>https://www.sylgalaxy.xyz/posts/cpp-concurrency-sync/</link><pubDate>Tue, 13 Oct 2026 00:00:00 +0000</pubDate><guid>https://www.sylgalaxy.xyz/posts/cpp-concurrency-sync/</guid><description>&lt;p&gt;线程创建与 join/detach 之外的另一半问题：共享数据怎么同步。覆盖数据竞争、互斥锁的三种用法、条件变量生产者-消费者、原子操作与死锁。&lt;/p&gt;
&lt;h2 id="核心概念速查"&gt;核心概念速查&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;概念&lt;/th&gt;
&lt;th&gt;说明&lt;/th&gt;
&lt;th&gt;关键点&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;互斥锁&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;同一时刻只允许一个线程进入&lt;/td&gt;
&lt;td&gt;&lt;code&gt;std::mutex&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;lock_guard&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;RAII 自动加解锁&lt;/td&gt;
&lt;td&gt;推荐,防遗漏&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;unique_lock&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;更灵活的 RAII 锁&lt;/td&gt;
&lt;td&gt;可手动解锁、可条件变量&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;条件变量&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;线程间的等待/通知&lt;/td&gt;
&lt;td&gt;&lt;code&gt;std::condition_variable&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;原子操作&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;无锁的线程安全&lt;/td&gt;
&lt;td&gt;&lt;code&gt;std::atomic&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;数据竞争&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;多线程同时访问共享数据&lt;/td&gt;
&lt;td&gt;未定义行为,必须防&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="为什么需要锁"&gt;为什么需要锁&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-cpp" data-lang="cpp"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// 无锁: 两个线程同时对 counter++ 可能丢失更新
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// counter++ 实际是&amp;#34;读-改-写&amp;#34;三步,可能交错
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; counter &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;void&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;add&lt;/span&gt;() {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;for&lt;/span&gt; (&lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; i &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;; i &lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;100000&lt;/span&gt;; &lt;span style="color:#f92672"&gt;++&lt;/span&gt;i)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;++&lt;/span&gt;counter; &lt;span style="color:#75715e"&gt;// 数据竞争!
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="互斥锁三种用法"&gt;互斥锁三种用法&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-cpp" data-lang="cpp"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;#include&lt;/span&gt; &lt;span style="color:#75715e"&gt;&amp;lt;mutex&amp;gt;&lt;/span&gt;&lt;span style="color:#75715e"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;std&lt;span style="color:#f92672"&gt;::&lt;/span&gt;mutex g_mutex;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// 方式1: 原始 lock/unlock(容易忘解锁,不推荐)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;void&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;f1&lt;/span&gt;() {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; g_mutex.lock();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// ... 临界区
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; g_mutex.unlock(); &lt;span style="color:#75715e"&gt;// 忘写或中间 return 就死锁
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// 方式2: lock_guard (推荐,作用域结束自动解锁)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;void&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;f2&lt;/span&gt;() {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; std&lt;span style="color:#f92672"&gt;::&lt;/span&gt;lock_guard&lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt;std&lt;span style="color:#f92672"&gt;::&lt;/span&gt;mutex&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt; guard(g_mutex);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// ... 临界区
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;} &lt;span style="color:#75715e"&gt;// 这里自动 unlock
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// 方式3: unique_lock (需要手动解锁/延迟加锁时)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;void&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;f3&lt;/span&gt;() {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; std&lt;span style="color:#f92672"&gt;::&lt;/span&gt;unique_lock&lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt;std&lt;span style="color:#f92672"&gt;::&lt;/span&gt;mutex&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt; lock(g_mutex);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// ... 临界区
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; lock.unlock();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// ... 不需要锁的部分
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="条件变量生产者-消费者"&gt;条件变量：生产者-消费者&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-cpp" data-lang="cpp"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;#include&lt;/span&gt; &lt;span style="color:#75715e"&gt;&amp;lt;mutex&amp;gt;&lt;/span&gt;&lt;span style="color:#75715e"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;#include&lt;/span&gt; &lt;span style="color:#75715e"&gt;&amp;lt;condition_variable&amp;gt;&lt;/span&gt;&lt;span style="color:#75715e"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;#include&lt;/span&gt; &lt;span style="color:#75715e"&gt;&amp;lt;queue&amp;gt;&lt;/span&gt;&lt;span style="color:#75715e"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;std&lt;span style="color:#f92672"&gt;::&lt;/span&gt;mutex mtx;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;std&lt;span style="color:#f92672"&gt;::&lt;/span&gt;condition_variable cv;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;std&lt;span style="color:#f92672"&gt;::&lt;/span&gt;queue&lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;int&lt;/span&gt;&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt; q;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// 生产者
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;void&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;producer&lt;/span&gt;() {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;for&lt;/span&gt; (&lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; i &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;; i &lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;10&lt;/span&gt;; &lt;span style="color:#f92672"&gt;++&lt;/span&gt;i) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; std&lt;span style="color:#f92672"&gt;::&lt;/span&gt;lock_guard&lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt;std&lt;span style="color:#f92672"&gt;::&lt;/span&gt;mutex&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt; lock(mtx);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; q.push(i);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; cv.notify_one(); &lt;span style="color:#75715e"&gt;// 通知一个等待的消费者
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// 消费者
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;void&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;consumer&lt;/span&gt;() {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;while&lt;/span&gt; (true) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; std&lt;span style="color:#f92672"&gt;::&lt;/span&gt;unique_lock&lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt;std&lt;span style="color:#f92672"&gt;::&lt;/span&gt;mutex&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt; lock(mtx);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// wait 会: 释放锁等待 → 被唤醒 → 重新加锁
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; cv.wait(lock, []{ &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; &lt;span style="color:#f92672"&gt;!&lt;/span&gt;q.empty(); });
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; val &lt;span style="color:#f92672"&gt;=&lt;/span&gt; q.front();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; q.pop();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; lock.unlock();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 处理 val...
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="原子操作"&gt;原子操作&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-cpp" data-lang="cpp"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;#include&lt;/span&gt; &lt;span style="color:#75715e"&gt;&amp;lt;atomic&amp;gt;&lt;/span&gt;&lt;span style="color:#75715e"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;std&lt;span style="color:#f92672"&gt;::&lt;/span&gt;atomic&lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;int&lt;/span&gt;&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt; counter{&lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;};
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// counter++ 是原子操作,无需加锁
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// 适用场景: 计数器、标志位、自旋
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// 对比:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// 普通 int ++ → 需 mutex
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// atomic ++ → 无锁,更快
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="死锁"&gt;死锁&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;死锁四个必要条件:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;1. 互斥 资源只能一个线程占用
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;2. 持有并等待 拿着一个锁还想要另一个
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;3. 不可剥夺 别人不能抢走已持有的锁
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;4. 循环等待 两个线程彼此持有对方要的锁
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;例子:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;线程A持锁1等锁2 + 线程B持锁2等锁1 → 死锁
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;避免: 全局加锁顺序一致 / 用 std::lock 一次锁多个
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="常见坑"&gt;常见坑&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;问题&lt;/th&gt;
&lt;th&gt;原因&lt;/th&gt;
&lt;th&gt;解决&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;死锁&lt;/td&gt;
&lt;td&gt;加锁顺序不一 / 忘解锁&lt;/td&gt;
&lt;td&gt;固定顺序 / &lt;code&gt;std::lock&lt;/code&gt; / RAII&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;假唤醒&lt;/td&gt;
&lt;td&gt;条件变量被无故唤醒&lt;/td&gt;
&lt;td&gt;&lt;code&gt;wait&lt;/code&gt; 用谓词条件,循环检查&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;性能差&lt;/td&gt;
&lt;td&gt;锁粒度太粗&lt;/td&gt;
&lt;td&gt;缩小临界区 / 用原子&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;数据竞争&lt;/td&gt;
&lt;td&gt;忘记加锁&lt;/td&gt;
&lt;td&gt;一律 RAII 锁,变量尽量用 atomic&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;忙等耗 CPU&lt;/td&gt;
&lt;td&gt;自旋锁滥用&lt;/td&gt;
&lt;td&gt;用条件变量阻塞等待&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="顿悟"&gt;顿悟&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;锁保护的是「数据」，不是「代码」&lt;/strong&gt;：所有访问同一个共享变量的地方都要用同一把锁，漏一处就出 bug。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;RAII 是防呆设计&lt;/strong&gt;：lock_guard 把&amp;quot;忘解锁&amp;quot;从可能性变成不可能，这是 C++ 现代写法核心。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;原子 ≠ 万能&lt;/strong&gt;：只能处理单个变量的简单操作；涉及多个变量的一致性仍需锁。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;条件变量的 wait 里一定有循环&lt;/strong&gt;：防止假唤醒，这是教科书写法，别省。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="自测清单"&gt;自测清单&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;理解数据竞争为什么会丢更新&lt;/li&gt;
&lt;li&gt;会用 &lt;code&gt;std::mutex&lt;/code&gt; + &lt;code&gt;std::lock_guard&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;区分 lock_guard 与 unique_lock 的适用场景&lt;/li&gt;
&lt;li&gt;能写生产者-消费者（条件变量）&lt;/li&gt;
&lt;li&gt;理解死锁四条件，知道如何避免&lt;/li&gt;
&lt;li&gt;知道什么时候用 &lt;code&gt;std::atomic&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>C++ 函数指针、std::function 与 lambda</title><link>https://www.sylgalaxy.xyz/posts/cpp-function-pointer-lambda/</link><pubDate>Tue, 13 Oct 2026 00:00:00 +0000</pubDate><guid>https://www.sylgalaxy.xyz/posts/cpp-function-pointer-lambda/</guid><description>&lt;p&gt;&amp;ldquo;把函数当值用&amp;quot;的三种写法：函数指针、&lt;code&gt;std::function&lt;/code&gt;、lambda。包含语法拆解、三者对比、捕获方式速记与常见坑。&lt;/p&gt;
&lt;h2 id="核心概念速查"&gt;核心概念速查&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;概念&lt;/th&gt;
&lt;th&gt;说明&lt;/th&gt;
&lt;th&gt;关键点&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;函数指针&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;存函数地址的变量&lt;/td&gt;
&lt;td&gt;C 风格,语法绕&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;std::function&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;通用函数包装器&lt;/td&gt;
&lt;td&gt;C++11,可存 lambda/仿函数&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;lambda&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;匿名函数对象&lt;/td&gt;
&lt;td&gt;C++11,现代首选&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;回调&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;函数指针的典型用途&lt;/td&gt;
&lt;td&gt;事件、排序、遍历&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;捕获&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;lambda 使用外部变量&lt;/td&gt;
&lt;td&gt;&lt;code&gt;[ ]&lt;/code&gt; &lt;code&gt;[&amp;amp;]&lt;/code&gt; &lt;code&gt;[=]&lt;/code&gt; &lt;code&gt;[x]&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="为什么需要函数指针"&gt;为什么需要函数指针&lt;/h2&gt;
&lt;p&gt;把&amp;quot;行为&amp;quot;作为参数传递，让代码更灵活。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-cpp" data-lang="cpp"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// 没有函数指针: 每有一种排序规则就要写一个函数
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;void&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;sort_ascending&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;int&lt;/span&gt;&lt;span style="color:#f92672"&gt;*&lt;/span&gt; arr, &lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; n);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;void&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;sort_descending&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;int&lt;/span&gt;&lt;span style="color:#f92672"&gt;*&lt;/span&gt; arr, &lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; n);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// 有函数指针: 一个排序函数,规则由调用方决定
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;void&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;sort&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;int&lt;/span&gt;&lt;span style="color:#f92672"&gt;*&lt;/span&gt; arr, &lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; n, &lt;span style="color:#66d9ef"&gt;bool&lt;/span&gt; (&lt;span style="color:#f92672"&gt;*&lt;/span&gt;compare)(&lt;span style="color:#66d9ef"&gt;int&lt;/span&gt;, &lt;span style="color:#66d9ef"&gt;int&lt;/span&gt;));
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="函数指针基础语法"&gt;函数指针基础语法&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-cpp" data-lang="cpp"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;#include&lt;/span&gt; &lt;span style="color:#75715e"&gt;&amp;lt;iostream&amp;gt;&lt;/span&gt;&lt;span style="color:#75715e"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// 定义两个比较函数
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;bool&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;ascending&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; a, &lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; b) { &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; a &lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt; b; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;bool&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;descending&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; a, &lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; b) { &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; a &lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt; b; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// 参数是函数指针: bool (*compare)(int, int)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;void&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;sort&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;int&lt;/span&gt;&lt;span style="color:#f92672"&gt;*&lt;/span&gt; arr, &lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; n, &lt;span style="color:#66d9ef"&gt;bool&lt;/span&gt; (&lt;span style="color:#f92672"&gt;*&lt;/span&gt;compare)(&lt;span style="color:#66d9ef"&gt;int&lt;/span&gt;, &lt;span style="color:#66d9ef"&gt;int&lt;/span&gt;)) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;for&lt;/span&gt; (&lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; i &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;; i &lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt; n &lt;span style="color:#f92672"&gt;-&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;; &lt;span style="color:#f92672"&gt;++&lt;/span&gt;i)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;for&lt;/span&gt; (&lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; j &lt;span style="color:#f92672"&gt;=&lt;/span&gt; i &lt;span style="color:#f92672"&gt;+&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;; j &lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt; n; &lt;span style="color:#f92672"&gt;++&lt;/span&gt;j)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; (compare(arr[j], arr[i])) &lt;span style="color:#75715e"&gt;// 调用比较函数
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; std&lt;span style="color:#f92672"&gt;::&lt;/span&gt;swap(arr[i], arr[j]);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;main&lt;/span&gt;() {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; arr[] &lt;span style="color:#f92672"&gt;=&lt;/span&gt; {&lt;span style="color:#ae81ff"&gt;3&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;4&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;5&lt;/span&gt;};
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; sort(arr, &lt;span style="color:#ae81ff"&gt;5&lt;/span&gt;, ascending); &lt;span style="color:#75715e"&gt;// 传函数名(自动转成指针)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// sort(arr, 5, &amp;amp;ascending); // 显式取地址也可以
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; sort(arr, &lt;span style="color:#ae81ff"&gt;5&lt;/span&gt;, descending);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;for&lt;/span&gt; (&lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; x : arr) std&lt;span style="color:#f92672"&gt;::&lt;/span&gt;cout &lt;span style="color:#f92672"&gt;&amp;lt;&amp;lt;&lt;/span&gt; x &lt;span style="color:#f92672"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34; &amp;#34;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;语法记忆&lt;/strong&gt;：&lt;code&gt;bool (*compare)(int, int)&lt;/code&gt; —— &lt;code&gt;*compare&lt;/code&gt; 是函数名，&lt;code&gt;(int,int)&lt;/code&gt; 是参数，&lt;code&gt;bool&lt;/code&gt; 是返回类型。不加括号 &lt;code&gt;bool *compare(...)&lt;/code&gt; 就变成返回指针的函数了。&lt;/p&gt;</description></item><item><title>C++ 基础遗漏知识点：bool、sizeof、auto、nullptr 与 static</title><link>https://www.sylgalaxy.xyz/posts/cpp-fundamentals-gotchas/</link><pubDate>Tue, 13 Oct 2026 00:00:00 +0000</pubDate><guid>https://www.sylgalaxy.xyz/posts/cpp-fundamentals-gotchas/</guid><description>&lt;p&gt;容易被忽略但常出问题的基础语法点：&lt;code&gt;bool&lt;/code&gt; 与 &lt;code&gt;boolalpha&lt;/code&gt;、&lt;code&gt;sizeof&lt;/code&gt; 的指针陷阱、&lt;code&gt;auto&lt;/code&gt; 的 const 剥离、&lt;code&gt;nullptr&lt;/code&gt; 与 &lt;code&gt;static&lt;/code&gt;。&lt;/p&gt;
&lt;h2 id="1-bool-类型与-boolalpha"&gt;1. bool 类型与 boolalpha&lt;/h2&gt;
&lt;h3 id="核心规则"&gt;核心规则&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;场景&lt;/th&gt;
&lt;th&gt;结果&lt;/th&gt;
&lt;th&gt;说明&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;bool b = true&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;输出 &lt;code&gt;1&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;默认输出数字&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;bool b = false&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;输出 &lt;code&gt;0&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;默认输出数字&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;bool b = -8&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;输出 &lt;code&gt;1&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;非零即为 true&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;bool b = 0&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;输出 &lt;code&gt;0&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;零即为 false&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id="boolalpha-操纵符"&gt;boolalpha 操纵符&lt;/h3&gt;
&lt;p&gt;使用 &lt;code&gt;std::boolalpha&lt;/code&gt; 可以让 &lt;code&gt;cout&lt;/code&gt; 输出 &lt;code&gt;true/false&lt;/code&gt; 而不是 &lt;code&gt;1/0&lt;/code&gt;。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-cpp" data-lang="cpp"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;#include&lt;/span&gt; &lt;span style="color:#75715e"&gt;&amp;lt;iostream&amp;gt;&lt;/span&gt;&lt;span style="color:#75715e"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;using&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;namespace&lt;/span&gt; std;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;main&lt;/span&gt;() {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;bool&lt;/span&gt; isTrue &lt;span style="color:#f92672"&gt;=&lt;/span&gt; true;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 默认输出（数字）
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; cout &lt;span style="color:#f92672"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;默认: &amp;#34;&lt;/span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;&amp;lt;&lt;/span&gt; isTrue &lt;span style="color:#f92672"&gt;&amp;lt;&amp;lt;&lt;/span&gt; endl; &lt;span style="color:#75715e"&gt;// 输出: 1
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 使用 boolalpha（文字）
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; cout &lt;span style="color:#f92672"&gt;&amp;lt;&amp;lt;&lt;/span&gt; boolalpha;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; cout &lt;span style="color:#f92672"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;boolalpha: &amp;#34;&lt;/span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;&amp;lt;&lt;/span&gt; isTrue &lt;span style="color:#f92672"&gt;&amp;lt;&amp;lt;&lt;/span&gt; endl; &lt;span style="color:#75715e"&gt;// 输出: true
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 非零值也为 true
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;bool&lt;/span&gt; b &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#f92672"&gt;-&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;8&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; cout &lt;span style="color:#f92672"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;-8 转 bool: &amp;#34;&lt;/span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;&amp;lt;&lt;/span&gt; b &lt;span style="color:#f92672"&gt;&amp;lt;&amp;lt;&lt;/span&gt; endl; &lt;span style="color:#75715e"&gt;// 输出: true
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="常见陷阱"&gt;常见陷阱&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-cpp" data-lang="cpp"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// 陷阱1：非零即为 true
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;bool&lt;/span&gt; b1 &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;42&lt;/span&gt;; &lt;span style="color:#75715e"&gt;// true
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;bool&lt;/span&gt; b2 &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#f92672"&gt;-&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;; &lt;span style="color:#75715e"&gt;// true
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;bool&lt;/span&gt; b3 &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0.001&lt;/span&gt;; &lt;span style="color:#75715e"&gt;// true
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;bool&lt;/span&gt; b4 &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;nullptr&lt;/span&gt;; &lt;span style="color:#75715e"&gt;// false (C++11)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// 陷阱2：bool 与整数混合运算
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; a &lt;span style="color:#f92672"&gt;=&lt;/span&gt; true &lt;span style="color:#f92672"&gt;+&lt;/span&gt; true; &lt;span style="color:#75715e"&gt;// a = 2（true 被提升为 1）
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; b &lt;span style="color:#f92672"&gt;=&lt;/span&gt; true &lt;span style="color:#f92672"&gt;*&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;10&lt;/span&gt;; &lt;span style="color:#75715e"&gt;// b = 10
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="2-sizeof-运算符"&gt;2. sizeof 运算符&lt;/h2&gt;
&lt;h3 id="基本用法"&gt;基本用法&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-cpp" data-lang="cpp"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;#include&lt;/span&gt; &lt;span style="color:#75715e"&gt;&amp;lt;iostream&amp;gt;&lt;/span&gt;&lt;span style="color:#75715e"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;using&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;namespace&lt;/span&gt; std;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;main&lt;/span&gt;() {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; cout &lt;span style="color:#f92672"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;char: &amp;#34;&lt;/span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;sizeof&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;char&lt;/span&gt;) &lt;span style="color:#f92672"&gt;&amp;lt;&amp;lt;&lt;/span&gt; endl; &lt;span style="color:#75715e"&gt;// 1
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; cout &lt;span style="color:#f92672"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;short: &amp;#34;&lt;/span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;sizeof&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;short&lt;/span&gt;) &lt;span style="color:#f92672"&gt;&amp;lt;&amp;lt;&lt;/span&gt; endl; &lt;span style="color:#75715e"&gt;// 2
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; cout &lt;span style="color:#f92672"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;int: &amp;#34;&lt;/span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;sizeof&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;int&lt;/span&gt;) &lt;span style="color:#f92672"&gt;&amp;lt;&amp;lt;&lt;/span&gt; endl; &lt;span style="color:#75715e"&gt;// 4
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; cout &lt;span style="color:#f92672"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;long: &amp;#34;&lt;/span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;sizeof&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;long&lt;/span&gt;) &lt;span style="color:#f92672"&gt;&amp;lt;&amp;lt;&lt;/span&gt; endl; &lt;span style="color:#75715e"&gt;// 4 或 8
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; cout &lt;span style="color:#f92672"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;long long: &amp;#34;&lt;/span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;sizeof&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;long&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;long&lt;/span&gt;) &lt;span style="color:#f92672"&gt;&amp;lt;&amp;lt;&lt;/span&gt; endl; &lt;span style="color:#75715e"&gt;// 8
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; cout &lt;span style="color:#f92672"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;float: &amp;#34;&lt;/span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;sizeof&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;float&lt;/span&gt;) &lt;span style="color:#f92672"&gt;&amp;lt;&amp;lt;&lt;/span&gt; endl; &lt;span style="color:#75715e"&gt;// 4
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; cout &lt;span style="color:#f92672"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;double: &amp;#34;&lt;/span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;sizeof&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;double&lt;/span&gt;) &lt;span style="color:#f92672"&gt;&amp;lt;&amp;lt;&lt;/span&gt; endl; &lt;span style="color:#75715e"&gt;// 8
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 数组
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; arr[&lt;span style="color:#ae81ff"&gt;10&lt;/span&gt;];
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; cout &lt;span style="color:#f92672"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;int[10]: &amp;#34;&lt;/span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;sizeof&lt;/span&gt;(arr) &lt;span style="color:#f92672"&gt;&amp;lt;&amp;lt;&lt;/span&gt; endl; &lt;span style="color:#75715e"&gt;// 40
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 指针
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;int&lt;/span&gt;&lt;span style="color:#f92672"&gt;*&lt;/span&gt; p;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; cout &lt;span style="color:#f92672"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;int*: &amp;#34;&lt;/span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;sizeof&lt;/span&gt;(p) &lt;span style="color:#f92672"&gt;&amp;lt;&amp;lt;&lt;/span&gt; endl; &lt;span style="color:#75715e"&gt;// 4 或 8
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="动态数组的-sizeof-陷阱"&gt;动态数组的 sizeof 陷阱&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-cpp" data-lang="cpp"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;int&lt;/span&gt;&lt;span style="color:#f92672"&gt;*&lt;/span&gt; arr &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;int&lt;/span&gt;[&lt;span style="color:#ae81ff"&gt;10&lt;/span&gt;];
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;cout &lt;span style="color:#f92672"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;sizeof&lt;/span&gt;(arr) &lt;span style="color:#f92672"&gt;&amp;lt;&amp;lt;&lt;/span&gt; endl; &lt;span style="color:#75715e"&gt;// 输出 4 或 8（指针大小，不是数组大小！）
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// 正确获取动态数组大小：需要额外传参或用 vector
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="3-auto-关键字c11"&gt;3. auto 关键字（C++11）&lt;/h2&gt;
&lt;h3 id="基本用法-1"&gt;基本用法&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-cpp" data-lang="cpp"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;auto&lt;/span&gt; x &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;42&lt;/span&gt;; &lt;span style="color:#75715e"&gt;// int
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;auto&lt;/span&gt; y &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;3.14&lt;/span&gt;; &lt;span style="color:#75715e"&gt;// double
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;auto&lt;/span&gt; z &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;hello&amp;#34;&lt;/span&gt;; &lt;span style="color:#75715e"&gt;// const char*
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;auto&lt;/span&gt; flag &lt;span style="color:#f92672"&gt;=&lt;/span&gt; true; &lt;span style="color:#75715e"&gt;// bool
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// 推荐用于复杂类型
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;#include&lt;/span&gt; &lt;span style="color:#75715e"&gt;&amp;lt;vector&amp;gt;&lt;/span&gt;&lt;span style="color:#75715e"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;#include&lt;/span&gt; &lt;span style="color:#75715e"&gt;&amp;lt;map&amp;gt;&lt;/span&gt;&lt;span style="color:#75715e"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;std&lt;span style="color:#f92672"&gt;::&lt;/span&gt;vector&lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;int&lt;/span&gt;&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt; v &lt;span style="color:#f92672"&gt;=&lt;/span&gt; {&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;3&lt;/span&gt;};
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;auto&lt;/span&gt; it &lt;span style="color:#f92672"&gt;=&lt;/span&gt; v.begin(); &lt;span style="color:#75715e"&gt;// std::vector&amp;lt;int&amp;gt;::iterator
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;std&lt;span style="color:#f92672"&gt;::&lt;/span&gt;map&lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt;std&lt;span style="color:#f92672"&gt;::&lt;/span&gt;string, &lt;span style="color:#66d9ef"&gt;int&lt;/span&gt;&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt; m;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;auto&lt;/span&gt; pair &lt;span style="color:#f92672"&gt;=&lt;/span&gt; std&lt;span style="color:#f92672"&gt;::&lt;/span&gt;make_pair(&lt;span style="color:#e6db74"&gt;&amp;#34;key&amp;#34;&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="注意事项"&gt;注意事项&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-cpp" data-lang="cpp"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// auto 会忽略顶层 const
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; a &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;10&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;auto&lt;/span&gt; b &lt;span style="color:#f92672"&gt;=&lt;/span&gt; a; &lt;span style="color:#75715e"&gt;// b 是 int，不是 const int
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;auto&lt;/span&gt; c &lt;span style="color:#f92672"&gt;=&lt;/span&gt; a; &lt;span style="color:#75715e"&gt;// c 是 const int
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// 引用形式的 auto 才保留底层 const
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;int&lt;/span&gt;&lt;span style="color:#f92672"&gt;&amp;amp;&lt;/span&gt; ref &lt;span style="color:#f92672"&gt;=&lt;/span&gt; a;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;auto&lt;/span&gt; ref2 &lt;span style="color:#f92672"&gt;=&lt;/span&gt; ref; &lt;span style="color:#75715e"&gt;// ref2 是 int 拷贝——普通 auto 剥离引用,连同底层 const 一起丢
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;auto&lt;/span&gt;&lt;span style="color:#f92672"&gt;&amp;amp;&lt;/span&gt; ref3 &lt;span style="color:#f92672"&gt;=&lt;/span&gt; ref; &lt;span style="color:#75715e"&gt;// ref3 是 const int&amp;amp;——auto&amp;amp; 保留底层 const(不能改 *ref3)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="4-nullptrc11"&gt;4. nullptr（C++11）&lt;/h2&gt;
&lt;h3 id="与-null-的区别"&gt;与 NULL 的区别&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-cpp" data-lang="cpp"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// NULL 在 C++ 中可能是 0 或 (void*)0
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;void&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;func&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;int&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;void&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;func&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;char&lt;/span&gt;&lt;span style="color:#f92672"&gt;*&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;func(NULL); &lt;span style="color:#75715e"&gt;// 编译错误！歧义
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;func(&lt;span style="color:#66d9ef"&gt;nullptr&lt;/span&gt;); &lt;span style="color:#75715e"&gt;// OK，调用 func(char*)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="最佳实践"&gt;最佳实践&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-cpp" data-lang="cpp"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// 初始化指针
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;int&lt;/span&gt;&lt;span style="color:#f92672"&gt;*&lt;/span&gt; p &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;nullptr&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// 判断指针
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; (p &lt;span style="color:#f92672"&gt;!=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;nullptr&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 使用 p
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// 函数参数
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;void&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;foo&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;int&lt;/span&gt;&lt;span style="color:#f92672"&gt;*&lt;/span&gt; ptr) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; (ptr &lt;span style="color:#f92672"&gt;==&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;nullptr&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="5-const-与-constexpr简记"&gt;5. const 与 constexpr（简记）&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;特性&lt;/th&gt;
&lt;th&gt;const&lt;/th&gt;
&lt;th&gt;constexpr&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;初始化时机&lt;/td&gt;
&lt;td&gt;运行时&lt;/td&gt;
&lt;td&gt;编译时&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;可用于函数返回值&lt;/td&gt;
&lt;td&gt;是&lt;/td&gt;
&lt;td&gt;是&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;编译期常量&lt;/td&gt;
&lt;td&gt;否&lt;/td&gt;
&lt;td&gt;是&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-cpp" data-lang="cpp"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; x &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;10&lt;/span&gt;; &lt;span style="color:#75715e"&gt;// OK
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;constexpr&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; y &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;20&lt;/span&gt;; &lt;span style="color:#75715e"&gt;// OK，编译期常量
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// constexpr 函数
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;constexpr&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;square&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; n) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; n &lt;span style="color:#f92672"&gt;*&lt;/span&gt; n;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;constexpr&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; val &lt;span style="color:#f92672"&gt;=&lt;/span&gt; square(&lt;span style="color:#ae81ff"&gt;5&lt;/span&gt;); &lt;span style="color:#75715e"&gt;// 编译期计算
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;const&lt;/code&gt; 与 &lt;code&gt;constexpr&lt;/code&gt; 的完整对比、&lt;code&gt;constexpr&lt;/code&gt; 函数、&lt;code&gt;if constexpr&lt;/code&gt;、C++20 的 &lt;code&gt;consteval&lt;/code&gt;/&lt;code&gt;constinit&lt;/code&gt;，见另一篇《C++ namespace、const 与 constexpr 知识点总结》。&lt;/p&gt;</description></item><item><title>C++ 网络编程基础：Socket API 与 TCP 通信</title><link>https://www.sylgalaxy.xyz/posts/cpp-socket-networking-basics/</link><pubDate>Tue, 13 Oct 2026 00:00:00 +0000</pubDate><guid>https://www.sylgalaxy.xyz/posts/cpp-socket-networking-basics/</guid><description>&lt;p&gt;围绕 Socket API 与 TCP/UDP 通信的核心概念、函数对照、示例代码与常见坑。&lt;/p&gt;
&lt;h2 id="核心概念速查"&gt;核心概念速查&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;概念&lt;/th&gt;
&lt;th&gt;说明&lt;/th&gt;
&lt;th&gt;关键点&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Socket&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;网络通信端点&lt;/td&gt;
&lt;td&gt;文件描述符抽象&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;TCP&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;面向连接、可靠&lt;/td&gt;
&lt;td&gt;三次握手、四次挥手&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;UDP&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;无连接、不可靠&lt;/td&gt;
&lt;td&gt;快速、轻量&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;sockaddr&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;通用地址结构&lt;/td&gt;
&lt;td&gt;IPv4/IPv6 统一接口&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;字节序&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;大端/小端转换&lt;/td&gt;
&lt;td&gt;&lt;code&gt;htons()&lt;/code&gt; &lt;code&gt;htonl()&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="tcp-三次握手与四次挥手"&gt;TCP 三次握手与四次挥手&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;三次握手(建立连接):
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Client ──SYN────▶ Server
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Client ◀─SYN+Ack─ Server
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Client ──Ack────▶ Server
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;四次挥手(关闭连接):
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Client ──FIN────▶ Server
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Client ◀─Ack───── Server
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Client ◀─FIN───── Server
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Client ──Ack────▶ Server
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="tcp-客户端-服务器模型"&gt;TCP 客户端-服务器模型&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;服务器: socket() → bind() → listen() → accept() → recv/send → close()
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;客户端: socket() → connect() → send/recv → close()
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="核心函数对照表"&gt;核心函数对照表&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;函数&lt;/th&gt;
&lt;th&gt;用途&lt;/th&gt;
&lt;th&gt;参数要点&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;socket()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;创建套接字&lt;/td&gt;
&lt;td&gt;&lt;code&gt;AF_INET, SOCK_STREAM, 0&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;bind()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;绑定地址&lt;/td&gt;
&lt;td&gt;套接字 + sockaddr_in&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;listen()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;监听连接&lt;/td&gt;
&lt;td&gt;backlog 队列长度&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;accept()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;接受连接&lt;/td&gt;
&lt;td&gt;返回新套接字描述符&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;connect()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;发起连接&lt;/td&gt;
&lt;td&gt;服务器地址&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;send/recv()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;发送/接收数据&lt;/td&gt;
&lt;td&gt;缓冲区 + 长度&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;htons/htonl()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;主机→网络字节序&lt;/td&gt;
&lt;td&gt;short/long&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;ntohs/ntohl()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;网络→主机字节序&lt;/td&gt;
&lt;td&gt;short/long&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="从-qt-到原生-socket"&gt;从 Qt 到原生 Socket&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Qt 写法&lt;/th&gt;
&lt;th&gt;原生等价物&lt;/th&gt;
&lt;th&gt;差异要点&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;server.listen(QHostAddress::Any, 8080)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;socket()&lt;/code&gt; + &lt;code&gt;bind()&lt;/code&gt; + &lt;code&gt;listen()&lt;/code&gt; 三步&lt;/td&gt;
&lt;td&gt;Qt 一行帮你做三件事&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;newConnection&lt;/code&gt; 信号 → &lt;code&gt;nextPendingConnection()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;accept()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Qt 信号通知;原生阻塞死等&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;socket-&amp;gt;connectToHost(&amp;quot;ip&amp;quot;, port)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;inet_pton()&lt;/code&gt; + &lt;code&gt;connect()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;IP 解析要自己做&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;socket-&amp;gt;write(bytes)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;send(fd, buf, len, 0)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;返回值要检查,可能只发一半&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;readyRead&lt;/code&gt; 信号 → &lt;code&gt;readAll()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;recv(fd, buf, size, 0)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;没有&amp;quot;就绪通知&amp;quot;,直接阻塞读&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;errorOccurred&lt;/code&gt; / &lt;code&gt;stateChanged&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;检查返回值 + &lt;code&gt;errno&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;错误要手动判断&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;QUdpSocket::writeDatagram/readDatagram&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;sendto()/recvfrom()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;多一个对端地址参数&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;QHostAddress(&amp;quot;127.0.0.1&amp;quot;)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;sockaddr_in&lt;/code&gt; + &lt;code&gt;inet_pton()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;字符串 IP 手动转结构体&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;端口字节序自动处理&lt;/td&gt;
&lt;td&gt;必须自己 &lt;code&gt;htons()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Qt 内部帮你转了&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;核心差异&lt;/strong&gt;：Qt 信号槽背后是「事件循环 + 就绪通知」(reactor 模式)。原生编程没有这个循环——要么阻塞死等，要么用线程，要么用 &lt;code&gt;select/epoll&lt;/code&gt; 自己搭事件循环。学原生网络的本质，就是把 Qt 隐藏的三件事（&lt;strong&gt;fd 管理、字节序、事件分发&lt;/strong&gt;）亲手做一遍。&lt;/p&gt;</description></item><item><title>C++ 线程基础：std::thread、join/detach 与传参陷阱</title><link>https://www.sylgalaxy.xyz/posts/cpp-thread-basics/</link><pubDate>Tue, 13 Oct 2026 00:00:00 +0000</pubDate><guid>https://www.sylgalaxy.xyz/posts/cpp-thread-basics/</guid><description>&lt;p&gt;&lt;code&gt;std::thread&lt;/code&gt; 的创建方式、join 与 detach 的语义、传参陷阱与常见坑。同步机制（互斥锁、条件变量、原子操作）见另一篇并发笔记。&lt;/p&gt;
&lt;h2 id="核心概念速查"&gt;核心概念速查&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;概念&lt;/th&gt;
&lt;th&gt;说明&lt;/th&gt;
&lt;th&gt;关键点&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;进程&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;独立运行的程序实例&lt;/td&gt;
&lt;td&gt;有独立内存空间&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;线程&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;进程内的执行单元&lt;/td&gt;
&lt;td&gt;共享进程内存&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;std::thread&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;C++11 线程库&lt;/td&gt;
&lt;td&gt;&lt;code&gt;#include &amp;lt;thread&amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;join&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;等待线程结束&lt;/td&gt;
&lt;td&gt;阻塞当前线程&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;detach&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;分离线程&lt;/td&gt;
&lt;td&gt;后台运行,不再可 join&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="进程-vs-线程"&gt;进程 vs 线程&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;维度&lt;/th&gt;
&lt;th&gt;进程&lt;/th&gt;
&lt;th&gt;线程&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;内存空间&lt;/td&gt;
&lt;td&gt;独立&lt;/td&gt;
&lt;td&gt;共享&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;通信&lt;/td&gt;
&lt;td&gt;管道/队列/文件&lt;/td&gt;
&lt;td&gt;直接共享变量(需同步)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;切换开销&lt;/td&gt;
&lt;td&gt;大&lt;/td&gt;
&lt;td&gt;小&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;创建开销&lt;/td&gt;
&lt;td&gt;大&lt;/td&gt;
&lt;td&gt;小&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;崩溃影响&lt;/td&gt;
&lt;td&gt;只影响自身&lt;/td&gt;
&lt;td&gt;可能带崩整个进程&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;适用场景&lt;/td&gt;
&lt;td&gt;隔离、分布式&lt;/td&gt;
&lt;td&gt;高并发、I/O 密集&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="创建线程"&gt;创建线程&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-cpp" data-lang="cpp"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;#include&lt;/span&gt; &lt;span style="color:#75715e"&gt;&amp;lt;iostream&amp;gt;&lt;/span&gt;&lt;span style="color:#75715e"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;#include&lt;/span&gt; &lt;span style="color:#75715e"&gt;&amp;lt;thread&amp;gt;&lt;/span&gt;&lt;span style="color:#75715e"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;void&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;hello&lt;/span&gt;() {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; std&lt;span style="color:#f92672"&gt;::&lt;/span&gt;cout &lt;span style="color:#f92672"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;Hello from thread&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;\n&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;main&lt;/span&gt;() {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 方式1: 无参函数
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; std&lt;span style="color:#f92672"&gt;::&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;thread&lt;/span&gt; t1(hello);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 方式2: lambda
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; std&lt;span style="color:#f92672"&gt;::&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;thread&lt;/span&gt; t2([]{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; std&lt;span style="color:#f92672"&gt;::&lt;/span&gt;cout &lt;span style="color:#f92672"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;Hello from lambda&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;\n&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; });
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 方式3: 带参函数
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;auto&lt;/span&gt; print_num &lt;span style="color:#f92672"&gt;=&lt;/span&gt; [](&lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; n) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; std&lt;span style="color:#f92672"&gt;::&lt;/span&gt;cout &lt;span style="color:#f92672"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;Number: &amp;#34;&lt;/span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;&amp;lt;&lt;/span&gt; n &lt;span style="color:#f92672"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;\n&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; };
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; std&lt;span style="color:#f92672"&gt;::&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;thread&lt;/span&gt; t3(print_num, &lt;span style="color:#ae81ff"&gt;42&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; t1.join();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; t2.join();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; t3.join();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="join-与-detach"&gt;join 与 detach&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;操作&lt;/th&gt;
&lt;th&gt;行为&lt;/th&gt;
&lt;th&gt;何时用&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;join()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;等待线程结束才继续&lt;/td&gt;
&lt;td&gt;需要线程结果时&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;detach()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;立即返回,线程后台跑&lt;/td&gt;
&lt;td&gt;结果不关心时(慎用)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;陷阱&lt;/strong&gt;：线程要么 join 要么 detach，都不做 → 析构时 &lt;code&gt;std::terminate()&lt;/code&gt; 崩溃。detach 的线程访问已销毁的对象 → 未定义行为。&lt;/p&gt;</description></item><item><title>C++ 服务部署实战：从源码到公网访问</title><link>https://www.sylgalaxy.xyz/posts/cpp-http-server-deploy/</link><pubDate>Tue, 25 Aug 2026 00:00:00 +0000</pubDate><guid>https://www.sylgalaxy.xyz/posts/cpp-http-server-deploy/</guid><description>&lt;blockquote&gt;
&lt;p&gt;在一台 2C2G 的云服务器上实测：单文件 HTTP 服务器，&lt;code&gt;g++&lt;/code&gt; 编译，监听 8080 端口，从编译到公网访问全流程跑通。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="1-socket-七步流程"&gt;1. socket 七步流程&lt;/h2&gt;
&lt;p&gt;示例是一个约 60 行的单文件程序 &lt;code&gt;http_server.cpp&lt;/code&gt;，纯 Linux socket API、零第三方依赖，放在你自己的项目目录里即可。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;socket() → bind() → listen() → accept() → recv() → send() → close()
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 建电话 插网线 开机待命 接电话 听需求 答复 挂断
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;步骤&lt;/th&gt;
&lt;th&gt;调用&lt;/th&gt;
&lt;th&gt;说明&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;&lt;code&gt;socket(AF_INET, SOCK_STREAM, 0)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;IPv4 + TCP，返回文件描述符（Linux 一切皆文件）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;&lt;code&gt;bind(fd, &amp;amp;addr, sizeof)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;绑定地址；&lt;code&gt;INADDR_ANY&lt;/code&gt;（0.0.0.0）= 监听所有网卡&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;&lt;code&gt;listen(fd, 16)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;开始待命；16 是 backlog 等待队列长度&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;&lt;code&gt;accept(fd, ...)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;阻塞等客户端，返回新 fd（每客户一个）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;&lt;code&gt;recv(fd, buf, n, 0)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;读 HTTP 请求报文（原始文本）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;6&lt;/td&gt;
&lt;td&gt;&lt;code&gt;send(fd, resp, len, 0)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;回 HTTP 响应&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;7&lt;/td&gt;
&lt;td&gt;&lt;code&gt;close(fd)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;挂断，回 while 等下一客&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;要点：&lt;/p&gt;</description></item><item><title>C++ 后端学习路线：以云服务器为练兵场</title><link>https://www.sylgalaxy.xyz/posts/cpp-backend-roadmap/</link><pubDate>Tue, 25 Aug 2026 00:00:00 +0000</pubDate><guid>https://www.sylgalaxy.xyz/posts/cpp-backend-roadmap/</guid><description>&lt;blockquote&gt;
&lt;p&gt;目标：从零起步，拿一台 2C2G 的云服务器当主战场，系统学习 C++ 后端开发。
原则：基础 → 系统 → 网络 → 框架 → 工程化，渐进推进；&lt;strong&gt;每个阶段都在云服务器上产出可运行的作品&lt;/strong&gt;。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="总览"&gt;总览&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;阶段&lt;/th&gt;
&lt;th&gt;主题&lt;/th&gt;
&lt;th&gt;周期&lt;/th&gt;
&lt;th&gt;云服务器上的产出&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;Linux 基础与服务器上手&lt;/td&gt;
&lt;td&gt;起步阶段，边用边补&lt;/td&gt;
&lt;td&gt;workspace 工作目录、用户与权限体系&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;现代 C++ 核心&lt;/td&gt;
&lt;td&gt;2-4 周&lt;/td&gt;
&lt;td&gt;编译与工具链的熟练度&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;Linux 系统与网络编程&lt;/td&gt;
&lt;td&gt;4-6 周&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;手写并发 HTTP 服务器&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;框架与中间件&lt;/td&gt;
&lt;td&gt;6-8 周&lt;/td&gt;
&lt;td&gt;Drogon + MySQL + Redis 的 REST API&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;工程化与云原生&lt;/td&gt;
&lt;td&gt;持续&lt;/td&gt;
&lt;td&gt;Docker 化部署 + CI/CD + 监控&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;blockquote&gt;
&lt;p&gt;时长按「每天 1-2 小时」估算，弹性理解；项目驱动，不以周数为硬指标。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;阶段 0 不必一次啃完：进程管理、看日志、shell 脚本这些内容在后面每个阶段都会反复用到，随用随补即可。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="阶段-0linux-基础与服务器上手"&gt;阶段 0：Linux 基础与服务器上手&lt;/h2&gt;
&lt;p&gt;这一层要覆盖的内容：&lt;/p&gt;</description></item></channel></rss>