<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/">
    <channel>
        <title>utto的学习屋</title>
        <link>https://www.yyshow.xyz/</link>
        <description>Recording Everything</description>
        <lastBuildDate>Wed, 22 Jul 2026 06:30:54 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <language>zh-CN</language>
        <copyright>All rights reserved 2026, utto</copyright>
        <item>
            <title><![CDATA[查找、排序与算法选择]]></title>
            <link>https://www.yyshow.xyz/article/search-sort-algorithm-selection</link>
            <guid>https://www.yyshow.xyz/article/search-sort-algorithm-selection</guid>
            <pubDate>Thu, 16 Jul 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[整理常见查找与排序算法、计数排序和基数排序，并比较不同数据结构与算法的适用场景。]]></description>
            <content:encoded><![CDATA[<div id="notion-article" class="mx-auto overflow-hidden "><main class="notion light-mode notion-page notion-block-39f560c488bc8186bbd6c52473de3c9c"><div class="notion-viewport"></div><div class="notion-collection-page-properties"></div><div class="notion-text notion-block-10cee30c3e0946a3be95d47871974751">本篇整理常见查找与排序算法，并从时间复杂度、空间开销和数据特征出发比较算法选择。</div><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-70a332bfe0c442e7b2b3ce127d0546b9" data-id="70a332bfe0c442e7b2b3ce127d0546b9"><span><div id="70a332bfe0c442e7b2b3ce127d0546b9" class="notion-header-anchor"></div><a class="notion-hash-link" href="#70a332bfe0c442e7b2b3ce127d0546b9" title="1. 查找算法"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">1. 查找算法</span></span></h3><div class="notion-text notion-block-e78837a46d4e4e089632775cac9cd71c">本章从「顺序查找」「二分查找」和「树表的查找」等方面说明查找算法。</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-faf5d5e699504cfcb8f5ce276f43b17c" data-id="faf5d5e699504cfcb8f5ce276f43b17c"><span><div id="faf5d5e699504cfcb8f5ce276f43b17c" class="notion-header-anchor"></div><a class="notion-hash-link" href="#faf5d5e699504cfcb8f5ce276f43b17c" title="1.1 顺序查找"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">1.1 顺序查找</span></span></h4><div class="notion-text notion-block-9acadcfe672f495e8b8e0b0e047faf96">查找过程为：从表中一端开始，依次比较表中元素和给定的目标值，如果元素值等于目标值，则查找成功。</div><div class="notion-text notion-block-5b587517d8014b4c82df7d1ed1f45a34">时间复杂度：O(N)</div><div class="notion-text notion-block-577cd4fcd79c49409c490e1bb4af27f7">空间复杂度：O(1)</div><div class="notion-text notion-block-72da0374fcc84cdb9c312a58832ef227">如果数组无序且数组规模比较小，那么可以使用；如果规模很大，这个实现性能会很差</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-5363934ea18a449b81b2b3d30fb684c6" data-id="5363934ea18a449b81b2b3d30fb684c6"><span><div id="5363934ea18a449b81b2b3d30fb684c6" class="notion-header-anchor"></div><a class="notion-hash-link" href="#5363934ea18a449b81b2b3d30fb684c6" title="1.2 二分查找"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">1.2 二分查找</span></span></h4><div class="notion-text notion-block-63d56816d10a4ae3836bf43a3bfe3b10">二分查找也称为折半查找。使用二分查找的前提是数组元素必须是有序的。查找过程为：给定一个数组和一个目标值，从表的中间位置开始记录，如果目标值和中间元素相同，则查找成功；如果中间元素小于或大于目标值，则在比中间值大或小的那一半中查找。重复操作，直到查找成功。实现代码有两种写法，取决于给定的查找范围是左闭右闭还是左闭右开的。</div><div class="notion-text notion-block-f1fad7c3685f4db1aea19ee0d369e01e">时间复杂度：O(logN)</div><div class="notion-text notion-block-86b9d1f4f94b41e7855fffe97352970f">空间复杂度：O(1)</div><div class="notion-text notion-block-1d61c7dccc4544abae9e6cafe975c478">时间复杂度计算过程：</div><div class="notion-text notion-block-8fb6c2e37d8b444fb27c826c18df6c92">第一次比较，剩余规模 n/2</div><div class="notion-text notion-block-9c21b906d930491695b23142bf56f6a5">第二次比较，剩余规模 n/4</div><div class="notion-text notion-block-53b0049d2e6f495e9a3d5d19c8a14b13">第三次比较，剩余规模 n/8</div><div class="notion-text notion-block-73b2aa64c3584c699e9604c45ef9eeb6">……</div><div class="notion-text notion-block-1976a03ca6074e549b3ec3485b07deb8">第 k 次比较，剩余规模 <span role="button" tabindex="0" class="notion-equation notion-equation-inline"><span></span></span></div><div class="notion-text notion-block-8dde8c81d7be4fff80fa09c028b193d4">在最坏情况下，搜索区间只剩最后一个元素，所以我们的 k 满足<span role="button" tabindex="0" class="notion-equation notion-equation-inline"><span></span></span>；</div><div class="notion-text notion-block-87204155134047f6b7d77f6b9809db5c">所以 <span role="button" tabindex="0" class="notion-equation notion-equation-inline"><span></span></span>，时间复杂度为 <span role="button" tabindex="0" class="notion-equation notion-equation-inline"><span></span></span></div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-cbe791fadfec47df9c51bba32c5c4f7c" data-id="cbe791fadfec47df9c51bba32c5c4f7c"><span><div id="cbe791fadfec47df9c51bba32c5c4f7c" class="notion-header-anchor"></div><a class="notion-hash-link" href="#cbe791fadfec47df9c51bba32c5c4f7c" title="1.3 树表的查找"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">1.3 树表的查找</span></span></h4><div class="notion-text notion-block-6a75e33f2b704279b51b928b41692d36">树表是利用树形结构组织的数据查找表，其目标是实现 <span role="button" tabindex="0" class="notion-equation notion-equation-inline"><span></span></span> 级别的高效查找、插入和删除操作。</div><h5 class="notion-h notion-h4 notion-h-indent-2 notion-block-b6311e9cb5034fb68216d65688d671d7" data-id="b6311e9cb5034fb68216d65688d671d7"><span><div id="b6311e9cb5034fb68216d65688d671d7" class="notion-header-anchor"></div><a class="notion-hash-link" href="#b6311e9cb5034fb68216d65688d671d7" title="1.3.1 二叉排序树（BST）"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">1.3.1 二叉排序树（BST）</span></span></h5><div class="notion-text notion-block-e95763b9d8314cd7a1ce10676e1ac19b">又称为二叉查找树、二叉搜索树，是一种特殊的二叉树，满足以下基本特性：</div><ol start="1" class="notion-list notion-list-numbered notion-block-d7e44408b5b4443aab40cf712ec01dd5" style="list-style-type:decimal"><li>左小右大：左边的节点小于中间的节点，中间的节点小于右边的节点</li></ol><ol start="2" class="notion-list notion-list-numbered notion-block-4709582be3c745eb9de437ff3b8463e2" style="list-style-type:decimal"><li>左右子树本身也分别是二叉排序树</li></ol><ol start="3" class="notion-list notion-list-numbered notion-block-963295fdeebe45a6b00b68c341397992" style="list-style-type:decimal"><li>中序遍历 BST 得到的序列是完全有序的</li></ol><div class="notion-text notion-block-3a8024649afc422fb6194924e24e54c2">平均时间复杂度：O(log N)</div><div class="notion-text notion-block-8746fd1dd21d4d3aaf3be026fe78e223">最坏时间复杂度：O(N)</div><h5 class="notion-h notion-h4 notion-h-indent-2 notion-block-3e4b266c0cc4427198d88c5b28df26f7" data-id="3e4b266c0cc4427198d88c5b28df26f7"><span><div id="3e4b266c0cc4427198d88c5b28df26f7" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3e4b266c0cc4427198d88c5b28df26f7" title="1.3.2 平衡二叉树（AVL）"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">1.3.2 平衡二叉树（AVL）</span></span></h5><div class="notion-text notion-block-e35a15993652475d9b0143b1b301bfc8">是最早被发明的自平衡二叉树，严格满足以下特性：</div><ol start="1" class="notion-list notion-list-numbered notion-block-2dd4d54555014327b6a5e17d163fea50" style="list-style-type:decimal"><li>任意节点左右子树的高度差的绝对值不超过 1</li></ol><ol start="2" class="notion-list notion-list-numbered notion-block-6752b33a6ccf4778926195b773e02122" style="list-style-type:decimal"><li>平衡因子 = 左子树高度 − 右子树高度</li></ol><div class="notion-text notion-block-361b5a8c2d9b420c80a8858e6b02ee8d">平均时间复杂度（查找、增删）：O(log N)</div><h5 class="notion-h notion-h4 notion-h-indent-2 notion-block-1b66174c6f1f494fb8fea3e7f4bd4fdc" data-id="1b66174c6f1f494fb8fea3e7f4bd4fdc"><span><div id="1b66174c6f1f494fb8fea3e7f4bd4fdc" class="notion-header-anchor"></div><a class="notion-hash-link" href="#1b66174c6f1f494fb8fea3e7f4bd4fdc" title="1.3.3 红黑树"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">1.3.3 红黑树</span></span></h5><div class="notion-text notion-block-959d66232ec64118875a0d6cc658b8b7">红黑树是一种在平衡性和维护成本很好的折中的自平衡二叉排序树，每个节点被标记为黑色或红色。</div><div class="notion-text notion-block-1c2fde04e49c4a47bb2c03e53beb7e5a">满足以下规则：</div><ol start="1" class="notion-list notion-list-numbered notion-block-5b1ead60c2e54faa94d069cf736284ae" style="list-style-type:decimal"><li>根节点是黑色</li></ol><ol start="2" class="notion-list notion-list-numbered notion-block-b805f9c21b8346709f27e07a38255864" style="list-style-type:decimal"><li>叶子节点是黑色</li></ol><ol start="3" class="notion-list notion-list-numbered notion-block-8f8083a483a141c68d5098aff9067fba" style="list-style-type:decimal"><li>如果一个节点是红色，那么它的两个子节点必须是黑色</li></ol><ol start="4" class="notion-list notion-list-numbered notion-block-edfe9528d4cd4d928ed55585e9b1c4fc" style="list-style-type:decimal"><li>从任意节点出发到其所有叶子节点上包含的黑色节点数量必须相等（黑色平衡）</li></ol><div class="notion-text notion-block-f96a8347afe2436bab7f1967adee1ce6">平均时间复杂度（查找、增删）：O(log N)</div><h5 class="notion-h notion-h4 notion-h-indent-2 notion-block-5df9da1c5a3042c3ad93f9a2abd075d7" data-id="5df9da1c5a3042c3ad93f9a2abd075d7"><span><div id="5df9da1c5a3042c3ad93f9a2abd075d7" class="notion-header-anchor"></div><a class="notion-hash-link" href="#5df9da1c5a3042c3ad93f9a2abd075d7" title="1.3.4 B 树"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">1.3.4 B 树</span></span></h5><div class="notion-text notion-block-0cb78c0dd66e45f09d2ec3d97dfeb28c">B 树是一种多路搜索树，它的设计初衷是为了优化外部存储（如硬盘、SSD）的数据查找效率，与前面几种树的内存优化目标不同。</div><div class="notion-text notion-block-33253d7dc0ae459997b8101bf1bac3d7">查找复杂度：<span role="button" tabindex="0" class="notion-equation notion-equation-inline"><span></span></span>。虽然理论上与 <span role="button" tabindex="0" class="notion-equation notion-equation-inline"><span></span></span> 级别相似，但在外部存储中，M 越大，I／O 次数越少，实际性能越好。</div><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-36a6ed16dca8418186f19020016c2627" data-id="36a6ed16dca8418186f19020016c2627"><span><div id="36a6ed16dca8418186f19020016c2627" class="notion-header-anchor"></div><a class="notion-hash-link" href="#36a6ed16dca8418186f19020016c2627" title="2. 排序算法"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">2. 排序算法</span></span></h3><div class="notion-text notion-block-683b6c4666e14285810cd65e508f1fc2">本章从「直接插入排序」「二分插入排序」和「希尔排序」等方面说明排序算法。</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-292666ade5a84bb9a92cd4b42d6c2482" data-id="292666ade5a84bb9a92cd4b42d6c2482"><span><div id="292666ade5a84bb9a92cd4b42d6c2482" class="notion-header-anchor"></div><a class="notion-hash-link" href="#292666ade5a84bb9a92cd4b42d6c2482" title="2.1 直接插入排序"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">2.1 直接插入排序</span></span></h4><div class="notion-text notion-block-f987666e8bbd44798ebddb429f547728">基本思想：类似于我们整理扑克牌，逐个顺序比较后插入。将数组分为已排序和未排序两个部分，第一个元素放入已排序部分，和未排序部分比较，直到排序完成。</div><div class="notion-text notion-block-e0bef5175b7a43c8ab61840c9c0bf461">时间复杂度：</div><ul class="notion-list notion-list-disc notion-block-b8a41cbf48aa49feab530103479a3a42"><li>最好情况：O(n) - 数组已经有序</li></ul><ul class="notion-list notion-list-disc notion-block-dfcf54642c944aeebc4d845d9b1a4728"><li>最坏情况：O(n²) - 数组完全逆序</li></ul><ul class="notion-list notion-list-disc notion-block-ea963671167342bfae2b0cd885beb977"><li>平均情况：O(n²)</li></ul><div class="notion-text notion-block-6205e3fcbe274d2f9e7e258ba8cbe6e4">适用条件：当数据规模小、数据基本有序时可以使用。</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-6ecbc6f598c0466da2fb3ed046a4fcda" data-id="6ecbc6f598c0466da2fb3ed046a4fcda"><span><div id="6ecbc6f598c0466da2fb3ed046a4fcda" class="notion-header-anchor"></div><a class="notion-hash-link" href="#6ecbc6f598c0466da2fb3ed046a4fcda" title="2.2 二分插入排序"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">2.2 二分插入排序</span></span></h4><div class="notion-text notion-block-2c7b6697885a47ef93ddb1c487c1f2b4">基本思想：二分插入排序是对直接插入排序的优化，在寻找插入位置时用二分查找代替顺序查找，减少了比较次数，但是移动次数不变。</div><div class="notion-text notion-block-e35166c413964e60a854594cf48820b3">时间复杂度：</div><ul class="notion-list notion-list-disc notion-block-316657033bcd4ce2b8e7e9f4ad528b94"><li>比较次数：O(n log n)</li></ul><ul class="notion-list notion-list-disc notion-block-feec52441b3a48edaeb48b8b40497d05"><li>移动次数：O(n²)</li></ul><ul class="notion-list notion-list-disc notion-block-76196f8705c745368617c8cfdd4f4158"><li>总时间复杂度：O(n²)</li></ul><div class="notion-text notion-block-72918ce14eed4dd18915b35d01aa3844">适用条件：比较代价比较高的时候使用。</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-1ee3327366ad4965bd2c8df0305134a1" data-id="1ee3327366ad4965bd2c8df0305134a1"><span><div id="1ee3327366ad4965bd2c8df0305134a1" class="notion-header-anchor"></div><a class="notion-hash-link" href="#1ee3327366ad4965bd2c8df0305134a1" title="2.3 希尔排序"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">2.3 希尔排序</span></span></h4><div class="notion-text notion-block-d040d9bbc06f499086fa1c7d2b2a3fd2">基本思想：也是对直接插入排序改进，又称为缩小增量排序，分组比较代替逐个比较。将原序列分成多个子序列进行插入排序，缩小间隔。重复以上过程，直到排序完成。</div><div class="notion-text notion-block-480adf9804624e039e92552210f7e589">常见的增量序列：</div><ol start="1" class="notion-list notion-list-numbered notion-block-b5bb67cd03914d7b81767f870840a221" style="list-style-type:decimal"><li>希尔增量：n/2, n/4, …, 1</li></ol><ol start="2" class="notion-list notion-list-numbered notion-block-85764452a57a4d248d78466926badca0" style="list-style-type:decimal"><li>Hibbard 增量：1, 3, 7, 15, …, 2^k-1</li></ol><ol start="3" class="notion-list notion-list-numbered notion-block-0e7fadefd5294ab086ce150e852f9bef" style="list-style-type:decimal"><li>Sedgewick 增量：1, 5, 19, 41, …</li></ol><div class="notion-text notion-block-0a371fda4c6f44fcbe7c475c1976c9ef">时间复杂度：</div><ul class="notion-list notion-list-disc notion-block-26fa519608d84799bb620ef04ea9396e"><li>最好情况：O(n log n)</li></ul><ul class="notion-list notion-list-disc notion-block-a8fc7828d2c94b238c51e7d5872a0292"><li>最坏情况：O(n²) - 使用希尔增量时</li></ul><ul class="notion-list notion-list-disc notion-block-56d1b849ef544a55b4a5bdf14d4f1bc5"><li>平均情况：取决于增量序列</li></ul><div class="notion-text notion-block-615da01a22324895a8314bda6d0cc1bf">适用条件：中等规模数据时使用。</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-277f9aeaaddc4567a76ad579272384f7" data-id="277f9aeaaddc4567a76ad579272384f7"><span><div id="277f9aeaaddc4567a76ad579272384f7" class="notion-header-anchor"></div><a class="notion-hash-link" href="#277f9aeaaddc4567a76ad579272384f7" title="2.4 冒泡排序"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">2.4 冒泡排序</span></span></h4><div class="notion-text notion-block-b6e3d81557ba4edf99924ca9481e9637">基本思想：比较相邻元素，如果第一个元素比第二个元素大，则交换两个元素的位置。比较每一对•相邻元素，最后的元素一定是未排序中最大的。重复以上操作，直到排序完成。</div><div class="notion-text notion-block-df1f805c78fe43eb832ea2b6ba225f48">时间复杂度：</div><ul class="notion-list notion-list-disc notion-block-4191fc07723d430d8cbde135a10d63f1"><li>平均时间复杂度：O(N^2)</li></ul><ul class="notion-list notion-list-disc notion-block-6ee47685665e4d01be9ed5ddb0c22db3"><li>交换次数：O(N^2)</li></ul><ul class="notion-list notion-list-disc notion-block-bfb6e3e8e2624e8c9302437cd96b8285"><li>空间复杂度：O(1)</li></ul><div class="notion-text notion-block-366b92b3e6084dbc86e6c71967864dfe">适用条件：小规模数据、数组基本有序、内存受限的情况。</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-cd6e8cbb2ec2464d99b0e827e8c7696b" data-id="cd6e8cbb2ec2464d99b0e827e8c7696b"><span><div id="cd6e8cbb2ec2464d99b0e827e8c7696b" class="notion-header-anchor"></div><a class="notion-hash-link" href="#cd6e8cbb2ec2464d99b0e827e8c7696b" title="2.5 选择排序"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">2.5 选择排序</span></span></h4><div class="notion-text notion-block-b5fc9819c7264e7c8e000edff51fbd79">基本思想：在冒泡排序的基础上改进了交换次数，从第一个元素开始和后面的所有元素相比，比较出最小的元素，先记录下标，跟最后一个元素比较完之后再交换位置，得到最小元素。重复以上过程，直到排序完成。</div><div class="notion-text notion-block-a422a75be46747b58ce3bb649c248a68">时间复杂度：</div><ul class="notion-list notion-list-disc notion-block-fa6f1cbceb9047bcaeba8e4bfcd98ab7"><li>平均时间复杂度：<span role="button" tabindex="0" class="notion-equation notion-equation-inline"><span></span></span></li></ul><ul class="notion-list notion-list-disc notion-block-48beb2fe10194f2da6894a3eb6d2c527"><li>交换次数：O(N)</li></ul><ul class="notion-list notion-list-disc notion-block-eac609b6a11e4e2b9533d1d6b85448a2"><li>空间复杂度：O(1)</li></ul><div class="notion-text notion-block-8e10023374d04896a2add18939017eb3">适用条件：小规模数据且比较代价高，内存受限的情况。</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-bed62151328f48f3ab649d672a0f85d1" data-id="bed62151328f48f3ab649d672a0f85d1"><span><div id="bed62151328f48f3ab649d672a0f85d1" class="notion-header-anchor"></div><a class="notion-hash-link" href="#bed62151328f48f3ab649d672a0f85d1" title="2.6 快速排序"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">2.6 快速排序</span></span></h4><div class="notion-text notion-block-295b5c2d1578446ab66b052bd47e2113">基本思想：采用分治策略。选择一个基准元素，通过一趟排序将序列分隔成独立的两个部分，其中左边部分的所有元素比基准元素小，右边部分的所有元素都比基准元素大，然后再对这两个部分递归排序。</div><div class="notion-text notion-block-986a7937601247c0b6433304e8d056e4">其中基准元素一般选：第一个元素、最后一个元素、中间元素。</div><div class="notion-text notion-block-a9be55b5c1f3454fb7d06a579795daf5">时间复杂度</div><ul class="notion-list notion-list-disc notion-block-55d04bd8f8dc4eae82132c547732ad80"><li>平均时间复杂度：<span role="button" tabindex="0" class="notion-equation notion-equation-inline"><span></span></span></li></ul><ul class="notion-list notion-list-disc notion-block-2b2b0d9778084c83b4087ca8cc551e4b"><li>最坏时间复杂度：<span role="button" tabindex="0" class="notion-equation notion-equation-inline"><span></span></span></li></ul><ul class="notion-list notion-list-disc notion-block-2e49b22b2f78491ea347a74135a43a70"><li>空间复杂度：<span role="button" tabindex="0" class="notion-equation notion-equation-inline"><span></span></span></li></ul><div class="notion-text notion-block-58cd36d4ec5d46189d09ae7078c0e5dc">适用条件：当数据规模比较大、内存空间受限、数据分布随机时可以使用快排，但是如果数据分布本来就比较有序，选择最后一个元素作为基准时就容易将时间复杂度退化为<span role="button" tabindex="0" class="notion-equation notion-equation-inline"><span></span></span>。</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-1741d955b1344e5f82d7d862722a7e80" data-id="1741d955b1344e5f82d7d862722a7e80"><span><div id="1741d955b1344e5f82d7d862722a7e80" class="notion-header-anchor"></div><a class="notion-hash-link" href="#1741d955b1344e5f82d7d862722a7e80" title="2.7 堆排序"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">2.7 堆排序</span></span></h4><div class="notion-text notion-block-1dd5da1464ce494c82c6d9ad89d51a11">堆排序是一种树形选择排序，可以将待排序的数组看成是一颗完全二叉树的顺序存储结构。基本思想：排序规则是根节点小于或大于子节点，这样就可以将待排序序列构造成一个小顶堆或者是大顶堆。将堆顶元素和末尾元素交换，将剩余元素重新调整成堆，重复以上过程，直到堆中只剩一个元素。</div><div class="notion-text notion-block-c0b098e594fb474cbf9f2dd3641df56e">堆的特性：</div><ol start="1" class="notion-list notion-list-numbered notion-block-bc3dbd32572949b4a1ca862b04856d42" style="list-style-type:decimal"><li>结构性：堆是一颗完全二叉树，底层节点从左到右填入</li></ol><ol start="2" class="notion-list notion-list-numbered notion-block-ceb77774c4644605811bd1001fdc6bd0" style="list-style-type:decimal"><li>堆序性：</li></ol><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-39eb23f8d45f4dddb231c5c75513928a"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:100%;max-width:100%;flex-direction:column"><img style="object-fit:cover" src="https://www.notion.so/image/https%3A%2F%2Fprod-files-secure-apne1.s3.ap-northeast-1.amazonaws.com%2F1f5560c4-88bc-8103-920a-00030e171a50%2F50f5b2d3-e668-4c7e-9c2b-56962e56d5ba%2Fimage.png%3FX-Amz-Algorithm%3DAWS4-HMAC-SHA256%26X-Amz-Content-Sha256%3DUNSIGNED-PAYLOAD%26X-Amz-Credential%3DASIAZI2LB466ZWKWKUJC%252F20260716%252Fap-northeast-1%252Fs3%252Faws4_request%26X-Amz-Date%3D20260716T110012Z%26X-Amz-Expires%3D300%26X-Amz-Security-Token%3DIQoJb3JpZ2luX2VjEHoaDmFwLW5vcnRoZWFzdC0xIkcwRQIgCDenwVu05sX%252FEZJ6ss9mr8kluZA8CBr1MfEsgjCJhg0CIQC0pBqyL7m%252F4nRRMzMR5Y52Lwk5gtkt5ykBxgb1BRHvwiqGBAhDEAAaDDYzNzQyMzE4MzgwNSIMBKjKrlBVVZeLf5WfKuMDGH1cH47AmGu3sjElka75P8%252BfFayBZJF%252F417u9XXHxMXkBarhrO46IzbKkoOkOdzDsQ1eJSk91lFWqJOCWWQGiDCfn6C6eAaMXRP6TZoUg0UdN04kOLcL3zTaQSYQi8vvOOntbjWt%252FylPfvfzUoFaRz0a6x4mw5C9gOltLUyvTPeUMA3IMg0nXvB8HOorpzRnhFnEESnBivxtiE5TqvPFYg6RcuZdKyGNAII5XhF219W2PNM8lh5h%252FU%252F%252BGMYBDg%252Fi%252ByQqJuny7j8o%252BViejFtbdKLp3JpU707zTy5WjdRFt0yiNE9jnXM%252FlUL6srp7KC7wPEAxRHhozK2iSRgx6XB34TN%252FMarld161demUB31mmBmBMqSCGRc8fvki2STBUu7%252FKKXqTofxdh9YyIbDIhpPBpQ83OrS%252BdAO2%252FWuTc2CRjb3t%252BLZM9QST%252Bz9EK3HBCgzh5NSJp7DaltnnT1rsLzXnP%252Fe2GaZup8WYCPb42UwK7Vb0MqhE7Vngd3MVmM2Pue3WkjTM8j0mfGgHXRz%252FaJn%252FsXpdQv4Nk8EptYWPDekMXYB0XqCs2sGjLl2MPzunzdijshHoObHh3DkVm1iiX7Wc9TYzZXg0JP51Y7Gqu4eAT%252B1joDnCBEs6%252F%252FZVwZY8ANinKOwMJfY4tIGOqUB59B3SGFGQdQa8SgaITbG1CkroztbNyfla6mmDHzKeN6x%252BQyhPCteKtXXxaR2E%252FmkKyu3RFdeTPuk%252F%252Fy9ettjgW7D%252B7lEvLuOldyy5UekQLMnKwYSvLjOTs0SEpSJxqyzK8eqVMFhQ0%252FMhz%252F68ZB16BjST%252BCH%252FrIdZcsC%252FsxaQPj4s9iHm3r6ZQJu8IDJ5DX6eiAvHXGJtsFt2ES4XkV%252B%252Fr4r4WXd%26X-Amz-Signature%3Dad2dc2d63693169eac9e937c59e05da8e11c91fe0dffc1e2c3d2a8f7d85b5c04%26X-Amz-SignedHeaders%3Dhost%26x-amz-checksum-mode%3DENABLED%26x-id%3DGetObject%26spaceId%3D1f5560c4-88bc-8103-920a-00030e171a50?table=block&amp;id=39eb23f8-d45f-4ddd-b231-c5c75513928a&amp;t=39eb23f8-d45f-4ddd-b231-c5c75513928a&amp;width=1080&amp;cache=v2" alt="堆排序示意图" loading="lazy" decoding="async"/><figcaption class="notion-asset-caption">堆排序示意图</figcaption></div></figure><div class="notion-text notion-block-ff7516f902254bc29ece54d51673eaa1">时间复杂度：<span role="button" tabindex="0" class="notion-equation notion-equation-inline"><span></span></span>（平均、最好、最坏）</div><div class="notion-text notion-block-536981e295f2482bb5f1d43a1eb63dcb">空间复杂度：<span role="button" tabindex="0" class="notion-equation notion-equation-inline"><span></span></span></div><div class="notion-text notion-block-68785fe3b52c455698b45d3b03f49091">适用条件：内存受限，且需要时间复杂度保证的场景。</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-974145ce40b9460f8cdd9ebf4f5f1336" data-id="974145ce40b9460f8cdd9ebf4f5f1336"><span><div id="974145ce40b9460f8cdd9ebf4f5f1336" class="notion-header-anchor"></div><a class="notion-hash-link" href="#974145ce40b9460f8cdd9ebf4f5f1336" title="2.8 归并排序"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">2.8 归并排序</span></span></h4><div class="notion-text notion-block-72135a8be6704eeabac9ce32f7f855f5">本节从「分治法」「单链表实现」和「数组实现」等方面说明归并排序。</div><h5 class="notion-h notion-h4 notion-h-indent-2 notion-block-f47d2276f2b844b6891d0ac456c43d63" data-id="f47d2276f2b844b6891d0ac456c43d63"><span><div id="f47d2276f2b844b6891d0ac456c43d63" class="notion-header-anchor"></div><a class="notion-hash-link" href="#f47d2276f2b844b6891d0ac456c43d63" title="2.8.1 分治法"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">2.8.1 分治法</span></span></h5><div class="notion-text notion-block-6bc1b5743ae74d268935edf706496085">分治通常包含三个步骤：</div><ol start="1" class="notion-list notion-list-numbered notion-block-1550076cf7ef467099814802703161d5" style="list-style-type:decimal"><li>分解：将原问题拆成规模更小的子问题；</li></ol><ol start="2" class="notion-list notion-list-numbered notion-block-b823ef9dd7f94d9398f8126a04bb3c63" style="list-style-type:decimal"><li>解决：递归或迭代处理子问题；</li></ol><ol start="3" class="notion-list notion-list-numbered notion-block-6081f444aa11455c91900e5d6a5b7371" style="list-style-type:decimal"><li>合并：组合子问题结果。</li></ol><div class="notion-text notion-block-5ae0e16763e24e8fbc2e8af42e8150b9">归并排序把“合并”作为核心步骤；快速排序则通过分区把元素放到基准值两侧，再分别处理两个子区间。</div><h5 class="notion-h notion-h4 notion-h-indent-2 notion-block-a3c56c6bb896448da46dc557696e03cc" data-id="a3c56c6bb896448da46dc557696e03cc"><span><div id="a3c56c6bb896448da46dc557696e03cc" class="notion-header-anchor"></div><a class="notion-hash-link" href="#a3c56c6bb896448da46dc557696e03cc" title="2.8.2 单链表实现"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">2.8.2 单链表实现</span></span></h5><div class="notion-text notion-block-edc1072bc61d4bf6a21e4da374f671bf"><b>链表适合归并排序的原因：</b>链表可以通过调整指针合并有序序列，不依赖随机访问。</div><ul class="notion-list notion-list-disc notion-block-8e772addf15d4f16a7c75351bb85f70e"><li>找中点可使用快慢指针；</li></ul><ul class="notion-list notion-list-disc notion-block-67e7b7ef46b249379fa42bf779a5ce2a"><li>合并有序链表只需调整 next 指针；</li></ul><ul class="notion-list notion-list-disc notion-block-16617db773dd46878bc0da1b9f5a0420"><li>不依赖随机访问；</li></ul><ul class="notion-list notion-list-disc notion-block-06bf2f78fdb546978e1846df0255fe89"><li>时间复杂度稳定为 O(n log n)；</li></ul><ul class="notion-list notion-list-disc notion-block-a3414a757a16402bb24bbf0b3f90873b"><li>可以保持稳定性。</li></ul><div class="notion-text notion-block-4c3055a25ac54afd90530d09a8e1db01"><b>递归实现：</b>先使用快慢指针拆分链表，再递归排序并合并两个有序链表。</div><div class="notion-text notion-block-34246b9fd2614e18a9795e14cf55bdd0">复杂度：</div><ul class="notion-list notion-list-disc notion-block-aa6069ee58b54a8dac48071ea1e4d117"><li>时间复杂度：O(n log n)</li></ul><ul class="notion-list notion-list-disc notion-block-3dbc053838c64ec08003943d20d09349"><li>辅助空间复杂度：O(log n)，主要来自递归调用栈</li></ul><div class="notion-text notion-block-19c2290823834a9d9e3717e5317fb78f">边界条件中，下面这种写法：</div><div class="notion-text notion-block-84e63e98f4b54faeac36ae49ec43f049">在 <code class="notion-inline-code">head == nullptr</code> 时会发生空指针解引用，应写成：</div><div class="notion-text notion-block-cad66e15510942cbb6d8e3eb1ab4c73c"><b>优先队列中转法：</b>先把节点值放入小根堆，再按升序写回链表。</div><div class="notion-text notion-block-4a08899e7bb54182a55ae352de3491cc">将节点值放入小根堆，再按顺序写回：</div><ul class="notion-list notion-list-disc notion-block-39bd554b24f84f49b18cb46759c3a1ef"><li>时间复杂度：O(n log n)</li></ul><ul class="notion-list notion-list-disc notion-block-899cc1e952e4434a8a8ac6c7850c0b9b"><li>空间复杂度：O(n)</li></ul><ul class="notion-list notion-list-disc notion-block-58a88f0d8f7f43c890be8d21fe86d15a"><li>实现简单；</li></ul><ul class="notion-list notion-list-disc notion-block-512a6d389e4643d99eaa26a0e4aac115"><li>只改变值，不改变节点顺序。</li></ul><div class="notion-text notion-block-f2ce1440c34442bf8b3a7f18aa66593f">如果题目要求真正重排节点、节点身份有意义，或节点除 <code class="notion-inline-code">val</code> 外还含有相关数据，只交换/覆盖 <code class="notion-inline-code">val</code> 可能不符合要求。</div><h5 class="notion-h notion-h4 notion-h-indent-2 notion-block-1ff6684b622c4c93b51eb43356ff06af" data-id="1ff6684b622c4c93b51eb43356ff06af"><span><div id="1ff6684b622c4c93b51eb43356ff06af" class="notion-header-anchor"></div><a class="notion-hash-link" href="#1ff6684b622c4c93b51eb43356ff06af" title="2.8.3 数组实现"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">2.8.3 数组实现</span></span></h5><div class="notion-text notion-block-4cd4e663bc67419f8bc2fac11d0c6b00">复杂度：</div><ul class="notion-list notion-list-disc notion-block-67e7ddea12764bbc82289a217c0fa984"><li>时间复杂度：O(n log n)</li></ul><ul class="notion-list notion-list-disc notion-block-3121bbbc1dd14829a5854d569a4246c3"><li>空间复杂度：O(n)</li></ul><ul class="notion-list notion-list-disc notion-block-6c143888f5e64428b2df2761f87fe981"><li>稳定：在相等时优先取左侧元素</li></ul><div class="notion-text notion-block-824ea3fdb32d4452b98c1c18e070d027">常见应用：</div><ul class="notion-list notion-list-disc notion-block-438e0472dda241f18a6ab52911af70c6"><li>逆序对；</li></ul><ul class="notion-list notion-list-disc notion-block-723bca59de9e49e3bb0016372be4d0e6"><li>外部排序；</li></ul><ul class="notion-list notion-list-disc notion-block-69696947b0164076979793c72ab62afa"><li>链表排序；</li></ul><ul class="notion-list notion-list-disc notion-block-4cb7095369b444378258cfe4ee340c85"><li>需要稳定性的排序。</li></ul><blockquote class="notion-quote notion-block-7b76bb905cb7495da18d3e834699198a"><div>数组归并排序和链表归并排序示例已使用 C++17 编译，并在开启 <code class="notion-inline-code">-Wall -Wextra -Wpedantic -Werror</code> 后通过空数组、重复值、负数及链表排序测试。</div></blockquote><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-d4903746c7ab4822ba592d6f8d5f7cf3" data-id="d4903746c7ab4822ba592d6f8d5f7cf3"><span><div id="d4903746c7ab4822ba592d6f8d5f7cf3" class="notion-header-anchor"></div><a class="notion-hash-link" href="#d4903746c7ab4822ba592d6f8d5f7cf3" title="2.9 桶排序"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">2.9 桶排序</span></span></h4><div class="notion-text notion-block-b6eea3b8b52345c69a2226d7f81eb544">基本思想：桶排序的思想不是基于比较来实现的，而是通过分配来实现的一种排序算法。设置固定数量的空桶；遍历数组，将每个元素放入对应的桶里；对每个非空桶进行排序，按照顺序把每个桶里的元素放回原数组。</div><div class="notion-text notion-block-0c5b42973c0d4ed08d274850f1a7bf47">平均时间复杂度：<span role="button" tabindex="0" class="notion-equation notion-equation-inline"><span></span></span></div><div class="notion-text notion-block-18019ace0ef14b61bb1379c27b7ed192">最坏时间复杂度：<span role="button" tabindex="0" class="notion-equation notion-equation-inline"><span></span></span></div><div class="notion-text notion-block-ebb96e0cf5ae4e64ab5e6d0b8d8d1eb9">空间复杂度：<span role="button" tabindex="0" class="notion-equation notion-equation-inline"><span></span></span></div><div class="notion-text notion-block-418bd1d372784caaa74c5b206565019d">适用条件：数据分布均匀，数据范围有限。如整理扑克牌、给学生成绩排序。</div><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-96d01d12c77349ea9c8f0d889f4c598b" data-id="96d01d12c77349ea9c8f0d889f4c598b"><span><div id="96d01d12c77349ea9c8f0d889f4c598b" class="notion-header-anchor"></div><a class="notion-hash-link" href="#96d01d12c77349ea9c8f0d889f4c598b" title="3. 计数排序与基数排序"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">3. 计数排序与基数排序</span></span></h3><div class="notion-text notion-block-bc7dc60d7a43485489b5af83589fe32e">本章围绕「非比较排序」展开，先明确核心概念与适用边界。</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-c09ac55bbfbd48a58f48ba22137de716" data-id="c09ac55bbfbd48a58f48ba22137de716"><span><div id="c09ac55bbfbd48a58f48ba22137de716" class="notion-header-anchor"></div><a class="notion-hash-link" href="#c09ac55bbfbd48a58f48ba22137de716" title="3.1 非比较排序"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">3.1 非比较排序</span></span></h4><div class="notion-text notion-block-34340634d83548c199a14686ab8c699b">本节从「计数排序」和「基数排序」两方面说明非比较排序。</div><h5 class="notion-h notion-h4 notion-h-indent-2 notion-block-68c85a75deac42a29bbebb7694a561e5" data-id="68c85a75deac42a29bbebb7694a561e5"><span><div id="68c85a75deac42a29bbebb7694a561e5" class="notion-header-anchor"></div><a class="notion-hash-link" href="#68c85a75deac42a29bbebb7694a561e5" title="3.1.1 计数排序"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">3.1.1 计数排序</span></span></h5><ul class="notion-list notion-list-disc notion-block-68e32345dd71478eaea7f33b0d96e14e"><li>适合整数键范围较小；</li></ul><ul class="notion-list notion-list-disc notion-block-ddfd387493f2436db009c02a56df1f24"><li>时间复杂度通常为 O(n + k)；</li></ul><ul class="notion-list notion-list-disc notion-block-4f4e76aec37044acbebcdd81a6c577c6"><li>空间复杂度通常为 O(k)；</li></ul><ul class="notion-list notion-list-disc notion-block-21b35c85bca64e8e8e87c7b8335d95ba"><li>是否稳定取决于具体实现。</li></ul><h5 class="notion-h notion-h4 notion-h-indent-2 notion-block-15e70ae56d154a739216379185f5f6ec" data-id="15e70ae56d154a739216379185f5f6ec"><span><div id="15e70ae56d154a739216379185f5f6ec" class="notion-header-anchor"></div><a class="notion-hash-link" href="#15e70ae56d154a739216379185f5f6ec" title="3.1.2 基数排序"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">3.1.2 基数排序</span></span></h5><ul class="notion-list notion-list-disc notion-block-9798b81b03144904be8e92c92a593049"><li>按位或按字符分阶段排序；</li></ul><ul class="notion-list notion-list-disc notion-block-8295aa682ea6431fb56d6d55f06868b6"><li>每一阶段通常要求稳定的子排序；</li></ul><ul class="notion-list notion-list-disc notion-block-ea25fb77ae5442eaaae36ee55211d879"><li>复杂度取决于位数、基数和子排序；</li></ul><ul class="notion-list notion-list-disc notion-block-899bac3dab834bb48fbff782ca08296d"><li>适合定长整数、字符串等特定键。</li></ul><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-8f31b5a976e2414bbcb927e63f13b7b0" data-id="8f31b5a976e2414bbcb927e63f13b7b0"><span><div id="8f31b5a976e2414bbcb927e63f13b7b0" class="notion-header-anchor"></div><a class="notion-hash-link" href="#8f31b5a976e2414bbcb927e63f13b7b0" title="4. 数据结构与算法选择建议"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">4. 数据结构与算法选择建议</span></span></h3><ul class="notion-list notion-list-disc notion-block-b565c9085ab94d7d871bc22d4a4cb1a6"><li><code class="notion-inline-code">vector</code> 和数组适合需要随机访问及缓存友好的场景。</li></ul><ul class="notion-list notion-list-disc notion-block-98a1bb171c004bb1a53d1be63ca5032e"><li>需要<b>链表排序</b>：优先归并排序。</li></ul><ul class="notion-list notion-list-disc notion-block-bca8374e78af4cb19338e6adc8834f9b"><li><code class="notion-inline-code">std::sort</code> 适合一般数组排序；只有在教学、特定分区需求或需要自定义行为时再手写快速排序。</li></ul><ul class="notion-list notion-list-disc notion-block-30ad451b37714a4bbcdf14cd0a5415e3"><li>只需要前 K 个：根据目标考虑维护大小为 <code class="notion-inline-code">k</code> 的堆；找最大的 K 个通常维护小根堆，找最小的 K 个通常维护大根堆。</li></ul><ul class="notion-list notion-list-disc notion-block-431df17948eb4014986e924f02fef12f"><li>查询很多且更新少：AVL 可能合适。</li></ul><ul class="notion-list notion-list-disc notion-block-a34613da8eba4b008c77428fccc94a90"><li>增删查综合平衡：红黑树类结构常见。</li></ul><ul class="notion-list notion-list-disc notion-block-2510a1f4929149b4aa506b1b86146745"><li>磁盘页和范围查询：B/B+ 树类结构。</li></ul><ul class="notion-list notion-list-disc notion-block-4fb4b9e92c0e4c1e8469cd95487dcc58"><li><code class="notion-inline-code">tuple</code> 可用于临时返回多个值。</li></ul><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-3c31c41569ac4c46bc34a87354d79dd0" data-id="3c31c41569ac4c46bc34a87354d79dd0"><span><div id="3c31c41569ac4c46bc34a87354d79dd0" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3c31c41569ac4c46bc34a87354d79dd0" title="5. 总结"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">5. 总结</span></span></h3><div class="notion-text notion-block-547fa1998d2f46579a819a2962c103f4">查找与排序算法没有脱离数据规模和分布的“唯一最优解”。选择时应比较时间复杂度、额外空间、稳定性、是否原地、数据是否近乎有序，以及键值范围能否支持计数或基数方法。</div><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-18923f371ac14d60be790a04ef75b2d4" data-id="18923f371ac14d60be790a04ef75b2d4"><span><div id="18923f371ac14d60be790a04ef75b2d4" class="notion-header-anchor"></div><a class="notion-hash-link" href="#18923f371ac14d60be790a04ef75b2d4" title="6. 参考资料"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">6. 参考资料</span></span></h3><ul class="notion-list notion-list-disc notion-block-efcc58843bd24da893170241049822d8"><li>严蔚敏、李冬梅、吴伟民：《数据结构（C 语言版·第 2 版）》。</li></ul><ul class="notion-list notion-list-disc notion-block-4fcc38b455294a9a9d676948d5d2ffbd"><li><a class="notion-link" href="https://programmercarl.com/" target="_blank" rel="noopener noreferrer">代码随想录</a></li></ul><ul class="notion-list notion-list-disc notion-block-87e3f9a0e1534bb79ac8b503af3072b0"><li><a class="notion-link" href="https://leetcode.cn/problemset/" target="_blank" rel="noopener noreferrer">LeetCode 题库</a></li></ul><div class="notion-blank notion-block-f545afb5f6e24d58a33fee8547a9a8d6"> </div></main></div>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[计算机组成原理笔记]]></title>
            <link>https://www.yyshow.xyz/article/computer-architecture-cpu-bits</link>
            <guid>https://www.yyshow.xyz/article/computer-architecture-cpu-bits</guid>
            <pubDate>Sat, 11 Jul 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[整理计算机系统组成、CPU 内部部件、取指—译码—执行流程、原码反码补码，以及 32/64 位程序、操作系统与兼容性。]]></description>
            <content:encoded><![CDATA[<div id="notion-article" class="mx-auto overflow-hidden "><main class="notion light-mode notion-page notion-block-399560c488bc8160aa1fee62674b7282"><div class="notion-viewport"></div><div class="notion-collection-page-properties"></div><div class="notion-blank notion-block-399560c488bc8056b55ac8f4b76303c8"> </div><blockquote class="notion-quote notion-block-9a664ccd8a6741bb8747d0faba74321f"><div>本文整理 CPU 内部结构、指令周期、原码/反码/补码，以及 32 位和 64 位体系。</div></blockquote><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-565b65d14c144689828281536451b9a0" data-id="565b65d14c144689828281536451b9a0"><span><div id="565b65d14c144689828281536451b9a0" class="notion-header-anchor"></div><a class="notion-hash-link" href="#565b65d14c144689828281536451b9a0" title="1. 计算机系统的基本组成"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">1. 计算机系统的基本组成</span></span></h3><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-eb38b3c5ab804a84b8a9ff6768c9bf7f"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:100%;max-width:100%;flex-direction:column"><img style="object-fit:cover" src="https://www.notion.so/image/https%3A%2F%2Fprod-files-secure-apne1.s3.ap-northeast-1.amazonaws.com%2F1f5560c4-88bc-8103-920a-00030e171a50%2Fb164e11a-d619-45ed-8fbc-11debe5d8ccc%2F6df482c3-8e5a-4281-ae8a-0e312fee3f35.jpg%3FX-Amz-Algorithm%3DAWS4-HMAC-SHA256%26X-Amz-Content-Sha256%3DUNSIGNED-PAYLOAD%26X-Amz-Credential%3DASIAZI2LB4665I6MSP4W%252F20260712%252Fap-northeast-1%252Fs3%252Faws4_request%26X-Amz-Date%3D20260712T182747Z%26X-Amz-Expires%3D300%26X-Amz-Security-Token%3DIQoJb3JpZ2luX2VjECEaDmFwLW5vcnRoZWFzdC0xIkgwRgIhAPkOph5HBBCcuYEyY5XRSvEqFpdeEPM2xrg%252BudgZnrlqAiEAti9SxxBSsBGdlc6khdMuJ4hTPhozrvoB%252BloxtAMWimoqjwQI6v%252F%252F%252F%252F%252F%252F%252F%252F%252F%252FARAAGgw2Mzc0MjMxODM4MDUiDAKwq8JqxidDFuIW%252BCrjA7WFzIzcTJrGvYO%252FYT7i%252FE3jjUe2BHUp255z9bYBMtIvKDAfHBXfXl%252FkK463KFXyuj8pZGGAf3ssI3Mze2Uy1meJ8vP4TYnC3MNkCZG3Ji9xNhFqFXl1fAdLv9USpy3yh2XSDQLFdur6IZmDqHPbzAvnw%252Fo3%252B03R5qSZV5oMtcfye9qQO7y6HFu5tafR1VIZlg6rPNBt5O7Yxr%252B2v5LMFkdcPrKD4sZBnb%252FuJy%252ByDAA9Bkxw%252FOvuOenGo8XLakcSLrHLmNJa9dulDnTGwuNLZvJ7egSE6brAFuhv8C%252FryjvZfTkKARyiP%252FMSxH4PMZJS575JXEumSKsWbMEekAA%252BSE56DQxj8h3dEoukcywBvctzxMxAaNf1VDVclBOpq2Jeqe%252BtFvoLrn4ZiWenRjbBGP1fIp%252FF%252FZlDZxUkF9qEdNDh2fSI7zcEYSL7jYI2re2yfOnJ2CidxEErRh6XETIXCrrCOHidxrsyytRExlJFrRGzKbokNs2jdUMH6xH6N0HWknIOCFZ0FP3KR%252FaHDmVqvbsvmPZk8EBJ92Wlr%252BmbK4ZkKF5d0FUaxIO9jht%252Fh%252FCI%252BLK2H673bRO3ChSIDJ4%252BWirXd3bnemKnNNExftSLkDO%252BSRBnc%252BHzMUrXS6tNQc%252Bm9l6q7jDfjM%252FSBjqkAcKYu4W%252F0oAESPgDYUs20zzCp4HArbcTeZec%252FMO6WN9M5oX3w6Top%252BCixJMx238ECfP96HUF5Md2EI9wVVLbtjcDAGVyhFTS98qjfK2S1kY3u0KT%252FJT6S67YfhS%252B8ig4cY0GB%252BisKrtau2O1I4TRlrJ7Vmu95SEjqlH3lkZOPUmB8QrcFkZTPvuq9z4%252BKEP5BwrYepMzIRjOjkmz%252BW0vcalSU7TM%26X-Amz-Signature%3Dd702dcc74077c3d84a31bf80036f5dd582ac6363853352703c82a4f5a6a814df%26X-Amz-SignedHeaders%3Dhost%26x-amz-checksum-mode%3DENABLED%26x-id%3DGetObject%26spaceId%3D1f5560c4-88bc-8103-920a-00030e171a50?table=block&amp;id=eb38b3c5-ab80-4a84-b8a9-ff6768c9bf7f&amp;t=eb38b3c5-ab80-4a84-b8a9-ff6768c9bf7f&amp;width=1080&amp;cache=v2" alt="计算机系统的基本组成示意图" loading="lazy" decoding="async"/><figcaption class="notion-asset-caption">计算机系统的基本组成示意图</figcaption></div></figure><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-8ae90357d4aa454995a91929fd482e29"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:100%;max-width:100%;flex-direction:column"><img style="object-fit:cover" src="https://www.notion.so/image/https%3A%2F%2Fprod-files-secure-apne1.s3.ap-northeast-1.amazonaws.com%2F1f5560c4-88bc-8103-920a-00030e171a50%2F8c5726c0-299b-4000-9beb-e3490ab6a6c7%2F711680aa-d1b6-4b1f-964a-d91c888054e4.png%3FX-Amz-Algorithm%3DAWS4-HMAC-SHA256%26X-Amz-Content-Sha256%3DUNSIGNED-PAYLOAD%26X-Amz-Credential%3DASIAZI2LB4665I6MSP4W%252F20260712%252Fap-northeast-1%252Fs3%252Faws4_request%26X-Amz-Date%3D20260712T182747Z%26X-Amz-Expires%3D300%26X-Amz-Security-Token%3DIQoJb3JpZ2luX2VjECEaDmFwLW5vcnRoZWFzdC0xIkgwRgIhAPkOph5HBBCcuYEyY5XRSvEqFpdeEPM2xrg%252BudgZnrlqAiEAti9SxxBSsBGdlc6khdMuJ4hTPhozrvoB%252BloxtAMWimoqjwQI6v%252F%252F%252F%252F%252F%252F%252F%252F%252F%252FARAAGgw2Mzc0MjMxODM4MDUiDAKwq8JqxidDFuIW%252BCrjA7WFzIzcTJrGvYO%252FYT7i%252FE3jjUe2BHUp255z9bYBMtIvKDAfHBXfXl%252FkK463KFXyuj8pZGGAf3ssI3Mze2Uy1meJ8vP4TYnC3MNkCZG3Ji9xNhFqFXl1fAdLv9USpy3yh2XSDQLFdur6IZmDqHPbzAvnw%252Fo3%252B03R5qSZV5oMtcfye9qQO7y6HFu5tafR1VIZlg6rPNBt5O7Yxr%252B2v5LMFkdcPrKD4sZBnb%252FuJy%252ByDAA9Bkxw%252FOvuOenGo8XLakcSLrHLmNJa9dulDnTGwuNLZvJ7egSE6brAFuhv8C%252FryjvZfTkKARyiP%252FMSxH4PMZJS575JXEumSKsWbMEekAA%252BSE56DQxj8h3dEoukcywBvctzxMxAaNf1VDVclBOpq2Jeqe%252BtFvoLrn4ZiWenRjbBGP1fIp%252FF%252FZlDZxUkF9qEdNDh2fSI7zcEYSL7jYI2re2yfOnJ2CidxEErRh6XETIXCrrCOHidxrsyytRExlJFrRGzKbokNs2jdUMH6xH6N0HWknIOCFZ0FP3KR%252FaHDmVqvbsvmPZk8EBJ92Wlr%252BmbK4ZkKF5d0FUaxIO9jht%252Fh%252FCI%252BLK2H673bRO3ChSIDJ4%252BWirXd3bnemKnNNExftSLkDO%252BSRBnc%252BHzMUrXS6tNQc%252Bm9l6q7jDfjM%252FSBjqkAcKYu4W%252F0oAESPgDYUs20zzCp4HArbcTeZec%252FMO6WN9M5oX3w6Top%252BCixJMx238ECfP96HUF5Md2EI9wVVLbtjcDAGVyhFTS98qjfK2S1kY3u0KT%252FJT6S67YfhS%252B8ig4cY0GB%252BisKrtau2O1I4TRlrJ7Vmu95SEjqlH3lkZOPUmB8QrcFkZTPvuq9z4%252BKEP5BwrYepMzIRjOjkmz%252BW0vcalSU7TM%26X-Amz-Signature%3Db564809b32262392159452500e5765eb5f8051a5e7a63237618d44400204bb4c%26X-Amz-SignedHeaders%3Dhost%26x-amz-checksum-mode%3DENABLED%26x-id%3DGetObject%26spaceId%3D1f5560c4-88bc-8103-920a-00030e171a50?table=block&amp;id=8ae90357-d4aa-4549-95a9-1929fd482e29&amp;t=8ae90357-d4aa-4549-95a9-1929fd482e29&amp;width=1080&amp;cache=v2" alt="计算机系统的基本组成示意图 2" loading="lazy" decoding="async"/><figcaption class="notion-asset-caption">计算机系统的基本组成示意图 2</figcaption></div></figure><div class="notion-text notion-block-37f67280f891410a8b83b83530bb3a11">从经典冯·诺依曼模型看，计算机系统通常由以下部分组成：</div><ul class="notion-list notion-list-disc notion-block-72c49aed68ec4090a167391bee6de4f6"><li>运算器；</li></ul><ul class="notion-list notion-list-disc notion-block-c87e9e66355546a7b41c6441250e9b64"><li>控制器；</li></ul><ul class="notion-list notion-list-disc notion-block-b38d0a843df242f18000db4674fd48ca"><li>存储器；</li></ul><ul class="notion-list notion-list-disc notion-block-e119432b47ea4048a80913850bb30403"><li>输入设备；</li></ul><ul class="notion-list notion-list-disc notion-block-2d410a3f27fb48bcb60035f5c9422dcc"><li>输出设备。</li></ul><div class="notion-text notion-block-e653c4b9b21646bf887981e4abeafa32">现代实现中，运算器和控制器等集成在 CPU 内；主存储器保存正在运行的程序和数据；I/O 控制器和外设负责输入输出。</div><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-8aa619fb305e4f4598e969ba90a9630c" data-id="8aa619fb305e4f4598e969ba90a9630c"><span><div id="8aa619fb305e4f4598e969ba90a9630c" class="notion-header-anchor"></div><a class="notion-hash-link" href="#8aa619fb305e4f4598e969ba90a9630c" title="2. CPU 内部主要部件"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">2. CPU 内部主要部件</span></span></h3><div class="notion-text notion-block-6f2d2109ebbe414b9fb78ae65295bef8">本章从「控制单元（CU）」「算术逻辑单元（ALU）」和「寄存器」等方面说明 CPU 内部主要部件。</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-e0d435e6e1e542ca9ecec1d90e5f913c" data-id="e0d435e6e1e542ca9ecec1d90e5f913c"><span><div id="e0d435e6e1e542ca9ecec1d90e5f913c" class="notion-header-anchor"></div><a class="notion-hash-link" href="#e0d435e6e1e542ca9ecec1d90e5f913c" title="2.1 控制单元（CU）"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">2.1 控制单元（CU）</span></span></h4><div class="notion-text notion-block-7179b22729ce420196193b2b909466b0">控制单元负责：</div><ul class="notion-list notion-list-disc notion-block-f2f85103195b457685331d972d332cd2"><li>获取指令；</li></ul><ul class="notion-list notion-list-disc notion-block-bf09a1cc9a074b3dbc60f9cc1b6200d2"><li>对指令进行译码；</li></ul><ul class="notion-list notion-list-disc notion-block-2f7b1fcf98cc4709b5c78bf311a35df2"><li>产生控制信号；</li></ul><ul class="notion-list notion-list-disc notion-block-7a5166fbd53446c3891643c055905724"><li>调度寄存器、执行单元、缓存和访存部件。</li></ul><div class="notion-text notion-block-d148df49f3024945a0d87a83140736fe">现代 CPU 的控制实现可能是硬连线控制、微程序控制或二者结合。</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-d9429d55cb6a47038a0df1760302c796" data-id="d9429d55cb6a47038a0df1760302c796"><span><div id="d9429d55cb6a47038a0df1760302c796" class="notion-header-anchor"></div><a class="notion-hash-link" href="#d9429d55cb6a47038a0df1760302c796" title="2.2 算术逻辑单元（ALU）"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">2.2 算术逻辑单元（ALU）</span></span></h4><div class="notion-text notion-block-0ef6a3cc5d464c01a4337fe80b8cb62e">ALU 负责整数算术和逻辑操作，例如：</div><ul class="notion-list notion-list-disc notion-block-8396c123bd0a4fba8dcc7c26551a8e3f"><li>加减；</li></ul><ul class="notion-list notion-list-disc notion-block-7ec02708f23d4c3c94d3fb92efe8c6a2"><li>位与、位或、异或、取反；</li></ul><ul class="notion-list notion-list-disc notion-block-1d117bf36e6d46a7a630413c74952547"><li>比较；</li></ul><ul class="notion-list notion-list-disc notion-block-899e258af65949d89c12d0a9722d1dd8"><li>移位。</li></ul><div class="notion-text notion-block-ea6d3209711d4a95adc03c7fc417980e">浮点运算通常由浮点执行单元负责；现代处理器还包含 SIMD/向量执行单元、地址生成单元等。</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-75eb906c14c54b3ca117f81593611e12" data-id="75eb906c14c54b3ca117f81593611e12"><span><div id="75eb906c14c54b3ca117f81593611e12" class="notion-header-anchor"></div><a class="notion-hash-link" href="#75eb906c14c54b3ca117f81593611e12" title="2.3 寄存器"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">2.3 寄存器</span></span></h4><div class="notion-text notion-block-cd5de76c3bd54b8f971f2d6d1dfa6a74">寄存器是 CPU 内部高速存储单元。</div><div class="notion-text notion-block-582a2f6eb666437aa7b0e24e3a03ab86">常见类别：</div><ul class="notion-list notion-list-disc notion-block-569680b0b9ca472f87218d5db53fb51a"><li><b>通用寄存器</b>：保存操作数、中间结果和地址。</li></ul><ul class="notion-list notion-list-disc notion-block-bd84f2e1ea3f4b61ba2acf7a076f5d64"><li><b>程序计数器 PC / 指令指针 IP</b>：保存下一条将要获取的指令地址。</li></ul><ul class="notion-list notion-list-disc notion-block-bd2ffcc9c12e4cc89bc0b6c94fb40e3c"><li><b>指令寄存器 IR</b>：教学模型中保存当前指令。</li></ul><ul class="notion-list notion-list-disc notion-block-6a13e7cc51dd479db51bb7aab5681713"><li><b>状态寄存器 / 标志寄存器</b>：记录零、进位、溢出、符号等状态。</li></ul><ul class="notion-list notion-list-disc notion-block-89f1d768122e4439b3a4d66cf961b123"><li><b>栈指针 SP</b>：指向当前栈顶。</li></ul><ul class="notion-list notion-list-disc notion-block-ce6c7d5163034b2d9859063e0331378b"><li><b>控制寄存器</b>：用于内存管理、特权级和系统控制。</li></ul><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-0f6a489f3f7741c1922d9078c715aa67" data-id="0f6a489f3f7741c1922d9078c715aa67"><span><div id="0f6a489f3f7741c1922d9078c715aa67" class="notion-header-anchor"></div><a class="notion-hash-link" href="#0f6a489f3f7741c1922d9078c715aa67" title="2.4 Cache"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">2.4 Cache</span></span></h4><div class="notion-text notion-block-1c63ac4db1444cd28bcde86a9319c637">Cache 保存近期或高概率再次访问的指令和数据，用来缩小 CPU 与主存之间的速度差距。</div><div class="notion-text notion-block-d649c15937b64bb39d729a9796dc59b4">常见层级：</div><div class="notion-text notion-block-ca3241e1db234ddb804e1430bf4d6119">Cache 不是简单的“数据和指令仓库”，还涉及缓存行、局部性、替换策略、写策略和一致性协议。</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-d5c61e7ce91f41fd93ffc82df53c1dfe" data-id="d5c61e7ce91f41fd93ffc82df53c1dfe"><span><div id="d5c61e7ce91f41fd93ffc82df53c1dfe" class="notion-header-anchor"></div><a class="notion-hash-link" href="#d5c61e7ce91f41fd93ffc82df53c1dfe" title="2.5 内部互连和总线"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">2.5 内部互连和总线</span></span></h4><div class="notion-text notion-block-6208c1bf890f4136b8c89b92fc47d29d">CPU 内部通过数据通路和互连结构连接寄存器、执行单元、缓存等部件。</div><div class="notion-text notion-block-6dc39046c70642b58632e6f9bcf617fa">系统层面常区分：</div><ul class="notion-list notion-list-disc notion-block-8efb5758a5c0424385678be1af6ce67c"><li>地址信息；</li></ul><ul class="notion-list notion-list-disc notion-block-89992cce11c040c3af85cca0945759b8"><li>数据信息；</li></ul><ul class="notion-list notion-list-disc notion-block-1d83e8671be34bbf8e403a8094d00679"><li>控制信息。</li></ul><div class="notion-text notion-block-d8a8475a85b442e1aacc18378a98d323">“数据总线、地址总线、控制总线”是功能上的分类，不应直接当作 CPU 的全部结构组成。</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-481fd40c492146e48e6a3c599aaf78b4" data-id="481fd40c492146e48e6a3c599aaf78b4"><span><div id="481fd40c492146e48e6a3c599aaf78b4" class="notion-header-anchor"></div><a class="notion-hash-link" href="#481fd40c492146e48e6a3c599aaf78b4" title="2.6 时钟、流水线和预测"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">2.6 时钟、流水线和预测</span></span></h4><div class="notion-text notion-block-ac7255cf937f43749f9424a4235e4d9a">现代 CPU 还常包含：</div><ul class="notion-list notion-list-disc notion-block-82214eb509d74d5a9376d03943ae262a"><li>时钟和时序电路；</li></ul><ul class="notion-list notion-list-disc notion-block-215a231be2984849aa89a9c1740c7189"><li>指令流水线；</li></ul><ul class="notion-list notion-list-disc notion-block-f9be807e7c96451ab2c4926736485c5c"><li>分支预测器；</li></ul><ul class="notion-list notion-list-disc notion-block-cd565214b8044478bc922bd2420b60e5"><li>乱序执行调度器；</li></ul><ul class="notion-list notion-list-disc notion-block-b8f47ba9430441899b72e523fcf968a0"><li>重排序缓冲区；</li></ul><ul class="notion-list notion-list-disc notion-block-f5129862cd4f4b908594bf4334159094"><li>取指、译码和发射单元。</li></ul><div class="notion-text notion-block-e86452d604e9463f966a440ed316c9a5">这些结构允许多条指令的不同阶段重叠执行。逻辑上仍可使用“取指—译码—执行”理解单条指令，但物理实现远比顺序模型复杂。</div><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-468e830c769a440c83a0a4c7d94539de" data-id="468e830c769a440c83a0a4c7d94539de"><span><div id="468e830c769a440c83a0a4c7d94539de" class="notion-header-anchor"></div><a class="notion-hash-link" href="#468e830c769a440c83a0a4c7d94539de" title="3. CPU 执行指令的基本过程"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">3. CPU 执行指令的基本过程</span></span></h3><div class="notion-text notion-block-79134d12b81a46ba9b00347a5bdf55d2">教学模型通常分为：</div><ol start="1" class="notion-list notion-list-numbered notion-block-74f8fd98c22b429dacd59be62d247e08" style="list-style-type:decimal"><li>取指；</li></ol><ol start="2" class="notion-list notion-list-numbered notion-block-a9af8a8e6a0344f5b0ca17657d9a3f6d" style="list-style-type:decimal"><li>译码；</li></ol><ol start="3" class="notion-list notion-list-numbered notion-block-188827bb8a6243f68bdde45b231f73d9" style="list-style-type:decimal"><li>执行；</li></ol><ol start="4" class="notion-list notion-list-numbered notion-block-64cbebe7588b4fdcb04a25bb489f786b" style="list-style-type:decimal"><li>访存（如需要）；</li></ol><ol start="5" class="notion-list notion-list-numbered notion-block-057d45bb87c743d1b90d31f6ad7c225d" style="list-style-type:decimal"><li>写回；</li></ol><ol start="6" class="notion-list notion-list-numbered notion-block-1376bd3976554d5c9805aeed8425f942" style="list-style-type:decimal"><li>更新下一条指令地址。</li></ol><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-dabe3e53306d4253911b86fbc4d9bf86" data-id="dabe3e53306d4253911b86fbc4d9bf86"><span><div id="dabe3e53306d4253911b86fbc4d9bf86" class="notion-header-anchor"></div><a class="notion-hash-link" href="#dabe3e53306d4253911b86fbc4d9bf86" title="3.1 取指"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">3.1 取指</span></span></h4><ul class="notion-list notion-list-disc notion-block-7e64e86859a74d8598bc2135e2f8aaf6"><li>PC 保存下一条指令地址；</li></ul><ul class="notion-list notion-list-disc notion-block-71742ec2f92c462b942c04e98349977c"><li>CPU 请求对应地址的指令；</li></ul><ul class="notion-list notion-list-disc notion-block-c0d4e4446d8e422aa12b15257f0facd3"><li>指令通过缓存层次或主存进入 CPU；</li></ul><ul class="notion-list notion-list-disc notion-block-586d525858234577a1d868a5c3d87743"><li>PC 更新为顺序下一地址，或之后被跳转目标覆盖。</li></ul><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-5ab2d196c6b14e1aaaab3e5a28da5589" data-id="5ab2d196c6b14e1aaaab3e5a28da5589"><span><div id="5ab2d196c6b14e1aaaab3e5a28da5589" class="notion-header-anchor"></div><a class="notion-hash-link" href="#5ab2d196c6b14e1aaaab3e5a28da5589" title="3.2 译码"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">3.2 译码</span></span></h4><div class="notion-text notion-block-436e815be5cd4c0eba691e07d994bc65">译码单元分析：</div><ul class="notion-list notion-list-disc notion-block-7757edd0175c4cc5a161aa4e4416feb6"><li>操作码；</li></ul><ul class="notion-list notion-list-disc notion-block-c02745370019450b8c721f052ca96e53"><li>源操作数；</li></ul><ul class="notion-list notion-list-disc notion-block-26214798475e4e0ead8572d94fe43c35"><li>目标操作数；</li></ul><ul class="notion-list notion-list-disc notion-block-39ef9237813c49ca8fb73f12e8cd71f1"><li>寻址方式；</li></ul><ul class="notion-list notion-list-disc notion-block-7535fc53daa94f02a951c68830c1afd5"><li>立即数；</li></ul><ul class="notion-list notion-list-disc notion-block-77ce0ded1f464ca79d7f61a184800bab"><li>是否需要访存或改变控制流。</li></ul><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-65e573482c6d4457886012c1e94264ef" data-id="65e573482c6d4457886012c1e94264ef"><span><div id="65e573482c6d4457886012c1e94264ef" class="notion-header-anchor"></div><a class="notion-hash-link" href="#65e573482c6d4457886012c1e94264ef" title="3.3 执行"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">3.3 执行</span></span></h4><div class="notion-text notion-block-8d9506b02b9445b08088094fcae990df">根据指令类型：</div><ul class="notion-list notion-list-disc notion-block-5b5135793a974edd8396bdf82593c4cf"><li>ALU 执行整数运算；</li></ul><ul class="notion-list notion-list-disc notion-block-b367bfdde0324dbe9333d5af770dbb95"><li>浮点/向量单元执行对应运算；</li></ul><ul class="notion-list notion-list-disc notion-block-4b148b1bbd43468aad90cd799efa5e96"><li>访存单元计算地址并读写缓存/内存；</li></ul><ul class="notion-list notion-list-disc notion-block-a81f3779d88b474cb079a621f95e9211"><li>分支指令修改控制流；</li></ul><ul class="notion-list notion-list-disc notion-block-bb2b6d7d7bf34b79b79008cac3d63730"><li>结果写回寄存器或内存。</li></ul><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-aadb61f557da49f89f9dfcdd2ee4b05f" data-id="aadb61f557da49f89f9dfcdd2ee4b05f"><span><div id="aadb61f557da49f89f9dfcdd2ee4b05f" class="notion-header-anchor"></div><a class="notion-hash-link" href="#aadb61f557da49f89f9dfcdd2ee4b05f" title="3.4 PC 如何递增"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">3.4 PC 如何递增</span></span></h4><div class="notion-text notion-block-40e4810416b34de2b5542d93ae188a57">PC 的更新步长由指令集和当前指令长度决定，不能直接由 CPU 位宽推断。</div><div class="notion-text notion-block-bb68f8d1bdbb4257a0a5b9365ab99caa">正确说法：</div><ul class="notion-list notion-list-disc notion-block-035694d4aea6436f8a29a0c7e8873514"><li>PC 按<b>指令长度</b>或 ISA 规定的指令宽度更新；</li></ul><ul class="notion-list notion-list-disc notion-block-7820dda96f484150a2ea8d1e085ebea4"><li>x86/x86-64 指令是变长的，一条指令可占不同字节数；</li></ul><ul class="notion-list notion-list-disc notion-block-2c03c58381e84df8b4f5f7c628332808"><li>AArch64 的常规指令通常为固定 4 字节；</li></ul><ul class="notion-list notion-list-disc notion-block-d6cf43b1aa08495e9a8ed24b1bfb3039"><li>遇到跳转、调用、返回、异常或中断时，PC 会改为目标地址；</li></ul><ul class="notion-list notion-list-disc notion-block-b1025b51468c452ba7add76c6d1821f0"><li>CPU 是 32 位还是 64 位，不能直接决定每条指令都占 4 或 8 字节。</li></ul><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-f71119dfd22b488db46373e5809c90bb" data-id="f71119dfd22b488db46373e5809c90bb"><span><div id="f71119dfd22b488db46373e5809c90bb" class="notion-header-anchor"></div><a class="notion-hash-link" href="#f71119dfd22b488db46373e5809c90bb" title="4. 原码、反码和补码"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">4. 原码、反码和补码</span></span></h3><div class="notion-text notion-block-ade32bc77bf94a9b8aaeacd46c7a8918">以下以 8 位有符号整数为例。</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-7d789f39c068413cbb464d8120f495d5" data-id="7d789f39c068413cbb464d8120f495d5"><span><div id="7d789f39c068413cbb464d8120f495d5" class="notion-header-anchor"></div><a class="notion-hash-link" href="#7d789f39c068413cbb464d8120f495d5" title="4.1 原码"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">4.1 原码</span></span></h4><ul class="notion-list notion-list-disc notion-block-3e9d7c90a5104b93b17bacfaf14281b7"><li>最高位表示符号：0 为正，1 为负；</li></ul><ul class="notion-list notion-list-disc notion-block-0d81f1cea6424c2e9b193760f63879cf"><li>其余位表示绝对值。</li></ul><div class="notion-text notion-block-433c54d2d37548769b8c7c32644ba941">问题：存在 <code class="notion-inline-code">+0</code> 和 <code class="notion-inline-code">-0</code> 两种零。</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-693570ff6ec24daaa2181410860200cd" data-id="693570ff6ec24daaa2181410860200cd"><span><div id="693570ff6ec24daaa2181410860200cd" class="notion-header-anchor"></div><a class="notion-hash-link" href="#693570ff6ec24daaa2181410860200cd" title="4.2 反码"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">4.2 反码</span></span></h4><ul class="notion-list notion-list-disc notion-block-01321330bd764265a3313ce7310bdbec"><li>正数反码与原码相同；</li></ul><ul class="notion-list notion-list-disc notion-block-ac4c914acbfd48b7a536b40b0b966a06"><li>负数符号位不变，其余位取反。</li></ul><div class="notion-text notion-block-370c32ba712f4115b593ba5ff25a45d5">仍然存在两种零。</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-63ceade0b07e4bfdaae942bdca653c97" data-id="63ceade0b07e4bfdaae942bdca653c97"><span><div id="63ceade0b07e4bfdaae942bdca653c97" class="notion-header-anchor"></div><a class="notion-hash-link" href="#63ceade0b07e4bfdaae942bdca653c97" title="4.3 补码"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">4.3 补码</span></span></h4><ul class="notion-list notion-list-disc notion-block-02621ff0b6b141b08373bceb7b587edc"><li>正数补码与原码相同；</li></ul><ul class="notion-list notion-list-disc notion-block-2c8e782f74ba45e7bfb95f584d6645a7"><li>负数补码通常可由“对应正数按位取反再加 1”得到。</li></ul><div class="notion-text notion-block-303083bbfc964ea68661f210cfff75d9">8 位补码范围：</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-8c3b96147a11437d808306735c5b1a0b" data-id="8c3b96147a11437d808306735c5b1a0b"><span><div id="8c3b96147a11437d808306735c5b1a0b" class="notion-header-anchor"></div><a class="notion-hash-link" href="#8c3b96147a11437d808306735c5b1a0b" title="4.4 为什么使用补码"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">4.4 为什么使用补码</span></span></h4><div class="notion-text notion-block-fefae5b382e94499848c06e9330e291e">本节从「零只有一种表示」和「加减法可以统一到加法器」两方面说明为什么使用补码。</div><h5 class="notion-h notion-h4 notion-h-indent-2 notion-block-8c274157719b41dc9a1cba9df65a6aa5" data-id="8c274157719b41dc9a1cba9df65a6aa5"><span><div id="8c274157719b41dc9a1cba9df65a6aa5" class="notion-header-anchor"></div><a class="notion-hash-link" href="#8c274157719b41dc9a1cba9df65a6aa5" title="4.4.1 零只有一种表示"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">4.4.1 零只有一种表示</span></span></h5><div class="notion-text notion-block-40d65892c25b47348cda9abf6db5317a">因此 8 位编码可以覆盖一个额外负数 <code class="notion-inline-code">-128</code>。</div><h5 class="notion-h notion-h4 notion-h-indent-2 notion-block-ce0a7d1f9ec94cc3990b79375ebea106" data-id="ce0a7d1f9ec94cc3990b79375ebea106"><span><div id="ce0a7d1f9ec94cc3990b79375ebea106" class="notion-header-anchor"></div><a class="notion-hash-link" href="#ce0a7d1f9ec94cc3990b79375ebea106" title="4.4.2 加减法可以统一到加法器"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">4.4.2 加减法可以统一到加法器</span></span></h5><div class="notion-text notion-block-cca225fa8cf8401aa1aa58d15d7b23ab">计算：</div><div class="notion-text notion-block-e7782a77b32d4f3fbecdb6e0dffcb621">可转换为：</div><div class="notion-text notion-block-993ee7d1c4204c06b10aa70af6f5a828">丢弃超出 8 位的最高进位，得到 <code class="notion-inline-code">0000 0010</code>，即 2。</div><div class="notion-text notion-block-a7552a5cc5514c67b064d18e01169a0c">更严谨地说，是将减法转换为加上被减数的相反数的补码，而不是笼统地说“加上这个数的补码”。</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-b47024998b694fbc838951aa82041ac6" data-id="b47024998b694fbc838951aa82041ac6"><span><div id="b47024998b694fbc838951aa82041ac6" class="notion-header-anchor"></div><a class="notion-hash-link" href="#b47024998b694fbc838951aa82041ac6" title="4.5 溢出"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">4.5 溢出</span></span></h4><div class="notion-text notion-block-6408b2d390454d6289a9ac7e92e331c0">固定宽度补码运算会溢出。</div><div class="notion-text notion-block-10adc820c301403cbd619a9d562c64f6">8 位有符号数：</div><div class="notion-text notion-block-181bdcf0615d48d5a9aaa4f09ab48eb7">位模式结果为：</div><div class="notion-text notion-block-e8be4043b4be4e2abf5c927ee071835c">按 8 位补码解释为 <code class="notion-inline-code">-128</code>。CPU 通常通过溢出标志等状态帮助软件判断。</div><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-04e1c906d60b47f5857448b1a1fbaeea" data-id="04e1c906d60b47f5857448b1a1fbaeea"><span><div id="04e1c906d60b47f5857448b1a1fbaeea" class="notion-header-anchor"></div><a class="notion-hash-link" href="#04e1c906d60b47f5857448b1a1fbaeea" title="5. 32 位和 64 位程序"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">5. 32 位和 64 位程序</span></span></h3><div class="notion-text notion-block-18bf897560dc4dfd8941d1b9fc3ae34b">本章从「32 位与 64 位的含义」「地址空间」和「数据模型」等方面说明 32 位和 64 位程序。</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-399560c488bc80c491f1fa37b8f977ef" data-id="399560c488bc80c491f1fa37b8f977ef"><span><div id="399560c488bc80c491f1fa37b8f977ef" class="notion-header-anchor"></div><a class="notion-hash-link" href="#399560c488bc80c491f1fa37b8f977ef" title="5.1 32 位与 64 位的含义"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">5.1 32 位与 64 位的含义</span></span></h4><div class="notion-text notion-block-399560c488bc80fdb5d9c31c625c6b0e">“32 位 CPU”或“64 位 CPU”并不是只指一个单一参数，常涉及：</div><ul class="notion-list notion-list-disc notion-block-399560c488bc80ed9fb3f8bde75f8423"><li>通用寄存器宽度；</li></ul><ul class="notion-list notion-list-disc notion-block-399560c488bc802c9ca8d320e03f8bed"><li>指令集架构；</li></ul><ul class="notion-list notion-list-disc notion-block-399560c488bc805bbb95f71922b19019"><li>地址计算能力；</li></ul><ul class="notion-list notion-list-disc notion-block-399560c488bc804a8995f93be1babc91"><li>指针和虚拟地址模型；</li></ul><ul class="notion-list notion-list-disc notion-block-399560c488bc8058901ac1dc4a0f6aff"><li>操作系统 ABI；</li></ul><ul class="notion-list notion-list-disc notion-block-399560c488bc8040aef4f502adc76ec5"><li>数据通路宽度。</li></ul><div class="notion-text notion-block-399560c488bc80e9bdbdd81c185dfe24">不同架构的具体实现可能不同。</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-5b57a327b8b44a03b2d77015b91752f1" data-id="5b57a327b8b44a03b2d77015b91752f1"><span><div id="5b57a327b8b44a03b2d77015b91752f1" class="notion-header-anchor"></div><a class="notion-hash-link" href="#5b57a327b8b44a03b2d77015b91752f1" title="5.2 地址空间"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">5.2 地址空间</span></span></h4><div class="notion-text notion-block-9f9a9979b3cb42c4b7a7ffecba2537f1">32 位指针理论上可编码：</div><div class="notion-text notion-block-bce782f532a44d3f972db15a9cba9393">单个 32 位进程通常只能使用其中一部分，具体划分取决于操作系统。</div><div class="notion-text notion-block-02c30680602a4ba08435bb29141f8c05">64 位指针理论上可编码 16 EiB，但现代处理器和操作系统通常只实现较少的有效虚拟地址位数，例如常见的 48 位或 57 位地址形式。不能把“64 位”直接等同于现实中可用 16 EiB 内存。</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-019a9ddeaf914fe286a0dc2d8126706e" data-id="019a9ddeaf914fe286a0dc2d8126706e"><span><div id="019a9ddeaf914fe286a0dc2d8126706e" class="notion-header-anchor"></div><a class="notion-hash-link" href="#019a9ddeaf914fe286a0dc2d8126706e" title="5.3 数据模型"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">5.3 数据模型</span></span></h4><div class="notion-text notion-block-67e7a9e944df45cea7ae8dccb899642c">常见模型：</div><ul class="notion-list notion-list-disc notion-block-e9acb3f3f5b84e40b21069a0863fbf03"><li><b>ILP32</b>：<code class="notion-inline-code">int</code>、<code class="notion-inline-code">long</code>、指针通常为 32 位；</li></ul><ul class="notion-list notion-list-disc notion-block-1456d3da24294c508eb034479902944b"><li><b>LP64</b>：<code class="notion-inline-code">long</code> 和指针为 64 位，<code class="notion-inline-code">int</code> 为 32 位，常见于 64 位 Linux/macOS；</li></ul><ul class="notion-list notion-list-disc notion-block-f1d5d8092c0d4cd4889e9da0760e8929"><li><b>LLP64</b>：<code class="notion-inline-code">long long</code> 和指针为 64 位，<code class="notion-inline-code">long</code> 仍为 32 位，常见于 64 位 Windows。</li></ul><div class="notion-text notion-block-09801c136c3043e7872af096695621a7">因此跨平台代码不能假设：</div><div class="notion-text notion-block-75178470a0fc4e4a8bc8aa1e6c9fffe4">应使用 <code class="notion-inline-code">sizeof</code>、固定宽度整数类型和 <code class="notion-inline-code">uintptr_t</code> 等进行判断。</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-b087f44b47eb46669bd08f31c4e4b835" data-id="b087f44b47eb46669bd08f31c4e4b835"><span><div id="b087f44b47eb46669bd08f31c4e4b835" class="notion-header-anchor"></div><a class="notion-hash-link" href="#b087f44b47eb46669bd08f31c4e4b835" title="5.4 指令集和寄存器"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">5.4 指令集和寄存器</span></span></h4><div class="notion-text notion-block-f36d8d2e3fcc4a9ab6a48948d0765f7d">以 x86 为例，x86-64：</div><ul class="notion-list notion-list-disc notion-block-2a233a157c074279a4ac3cc9ce6face4"><li>将部分通用寄存器扩展到 64 位；</li></ul><ul class="notion-list notion-list-disc notion-block-22577a78bc6147948f8e95b5aec4c6af"><li>增加了更多通用寄存器；</li></ul><ul class="notion-list notion-list-disc notion-block-80d944f74a7b4e32a85f74f2c6a52f42"><li>定义了新的调用约定和系统编程环境；</li></ul><ul class="notion-list notion-list-disc notion-block-71d829f7318d4788a11c9b563f6c73da"><li>提供 64 位地址和整数运算能力。</li></ul><div class="notion-text notion-block-4fd9a52167cf447d9b3aede136e6fd58">这些结论不能无条件推广到所有 CPU 架构。</div><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-581cb3ce585a421497373dfba980d65b" data-id="581cb3ce585a421497373dfba980d65b"><span><div id="581cb3ce585a421497373dfba980d65b" class="notion-header-anchor"></div><a class="notion-hash-link" href="#581cb3ce585a421497373dfba980d65b" title="6. 操作系统与程序兼容性"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">6. 操作系统与程序兼容性</span></span></h3><div class="notion-text notion-block-01d36054ddc74a4fbc81c97340e48473">本章从「64 位 CPU 能否安装 32 位操作系统」「32 位 CPU 能否运行 64 位操作系统」和「64 位操作系统能否运行 32 位程序」等方面说明操作系统与程序兼容性。</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-04df5e8010cb4071aa170dc8dfef3635" data-id="04df5e8010cb4071aa170dc8dfef3635"><span><div id="04df5e8010cb4071aa170dc8dfef3635" class="notion-header-anchor"></div><a class="notion-hash-link" href="#04df5e8010cb4071aa170dc8dfef3635" title="6.1 64 位 CPU 能否安装 32 位操作系统"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">6.1 64 位 CPU 能否安装 32 位操作系统</span></span></h4><div class="notion-text notion-block-41ebf80b6e5a451fbb994fd0291269a8">取决于该 CPU 是否保留对应兼容执行模式，以及设备是否仍有合适驱动。</div><div class="notion-text notion-block-199bbedd570b4233a5dd28b2ce8449ef">传统 x86-64 处理器通常可以运行 32 位 x86 操作系统，但此时操作系统运行在 32 位模式，不是“64 位长模式下的兼容子模式”。</div><div class="notion-text notion-block-6b84224425414e918047d51f07cbed4a">32 位系统仍可能通过 PAE 使用超过 4 GiB 的物理内存，但单个普通 32 位进程的虚拟地址空间仍受到 32 位地址范围限制。</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-510cba85077b47d9bd94f5279c632d90" data-id="510cba85077b47d9bd94f5279c632d90"><span><div id="510cba85077b47d9bd94f5279c632d90" class="notion-header-anchor"></div><a class="notion-hash-link" href="#510cba85077b47d9bd94f5279c632d90" title="6.2 32 位 CPU 能否运行 64 位操作系统"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">6.2 32 位 CPU 能否运行 64 位操作系统</span></span></h4><div class="notion-text notion-block-a3d67e60bddc411a8ccc47d4dec7bac9">不能直接运行要求 64 位指令集和执行模式的操作系统内核，因为 CPU 缺少对应指令、寄存器和系统机制。</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-a853f8be012b405686e1d4d66a75aca3" data-id="a853f8be012b405686e1d4d66a75aca3"><span><div id="a853f8be012b405686e1d4d66a75aca3" class="notion-header-anchor"></div><a class="notion-hash-link" href="#a853f8be012b405686e1d4d66a75aca3" title="6.3 64 位操作系统能否运行 32 位程序"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">6.3 64 位操作系统能否运行 32 位程序</span></span></h4><div class="notion-text notion-block-fd704035a4a2403bae5f42866d091d33">可能可以，但取决于：</div><ul class="notion-list notion-list-disc notion-block-51c77f6c4ba7415881578ec759d88a48"><li>操作系统是否提供兼容层；</li></ul><ul class="notion-list notion-list-disc notion-block-fd93156ebfd24ac88109af8092bc48c3"><li>是否安装 32 位运行库；</li></ul><ul class="notion-list notion-list-disc notion-block-75b8c852ffd949319b8ae2d8a4a19ac8"><li>CPU 是否支持相应执行模式；</li></ul><ul class="notion-list notion-list-disc notion-block-af5cafca4e624040a706dc682ddbd44f"><li>程序是否依赖已经移除的驱动或组件。</li></ul><div class="notion-text notion-block-af1c8f93d8a446e8b7277db747784882">64 位内核通常要求 64 位内核驱动，不能直接加载 32 位内核驱动。</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-4912d1aa432d4bf48fcad5751a71f7d3" data-id="4912d1aa432d4bf48fcad5751a71f7d3"><span><div id="4912d1aa432d4bf48fcad5751a71f7d3" class="notion-header-anchor"></div><a class="notion-hash-link" href="#4912d1aa432d4bf48fcad5751a71f7d3" title="6.4 64 位一定更快吗"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">6.4 64 位一定更快吗</span></span></h4><div class="notion-text notion-block-5815e0f821394d5abc87c7795d1276c2">不一定。</div><div class="notion-text notion-block-7fecd47cb5084594b41d2e83350d89e5">可能更快的场景：</div><ul class="notion-list notion-list-disc notion-block-e8010110f5b647128b71c7d3b7dafdd3"><li>需要超过 4 GiB 地址空间；</li></ul><ul class="notion-list notion-list-disc notion-block-a4cbd81ac2ea44a8acf4a88a08dacf3a"><li>大量 64 位整数运算；</li></ul><ul class="notion-list notion-list-disc notion-block-7ab54898b7084e0b969e2d0117e4ade4"><li>得益于更多寄存器和更好的调用约定；</li></ul><ul class="notion-list notion-list-disc notion-block-6332aa722b5f4dfd91515a02e373777c"><li>数据库、虚拟机、科学计算、大型内容生产。</li></ul><div class="notion-text notion-block-903cda75bfb84a45b57deddd546f72c1">可能没有优势或产生额外成本：</div><ul class="notion-list notion-list-disc notion-block-3c6e03c3411b4f18a5167af317cdcd05"><li>指针从 4 字节变为 8 字节，使数据结构变大；</li></ul><ul class="notion-list notion-list-disc notion-block-7ea21080c1354972868ffee2288b12c6"><li>缓存中能容纳的对象减少；</li></ul><ul class="notion-list notion-list-disc notion-block-f71fb080635047f5bf109f1665c182a3"><li>内存带宽和缓存压力增加；</li></ul><ul class="notion-list notion-list-disc notion-block-a8ab896e9d274210b651f48a5ce9018a"><li>程序主要受磁盘、网络或 GPU 限制；</li></ul><ul class="notion-list notion-list-disc notion-block-cb68b2a4f2dd4c3c9f1ddae490ba839d"><li>只处理小整数和小规模数据。</li></ul><div class="notion-text notion-block-5d222cda89cf48e9a0d4ed544deba08b">性能最终取决于程序、编译器、ABI、微架构、内存行为和工作负载。</div><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-485927e5d89e44729bc95ab6b8d10a04" data-id="485927e5d89e44729bc95ab6b8d10a04"><span><div id="485927e5d89e44729bc95ab6b8d10a04" class="notion-header-anchor"></div><a class="notion-hash-link" href="#485927e5d89e44729bc95ab6b8d10a04" title="7. 总结"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">7. 总结</span></span></h3><div class="notion-text notion-block-0b8c64f8dd2346869ef2606a1cf1814f">CPU 通过取指、译码和执行不断推进程序；补码让有符号整数的加减法可以复用同一套二进制运算规则。32 位与 64 位不仅影响寄存器和地址空间，也受到指令集、ABI、操作系统与应用依赖共同约束。</div><div class="notion-text notion-block-64305460e8624754891aeeafe31ff7fa">分析具体程序时，应明确讨论的是数据宽度、地址宽度、进程架构还是操作系统兼容层，避免把“64 位”简单等同于“必然更快”。</div><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-ccbefbd0b9e34996a267474f375a4f94" data-id="ccbefbd0b9e34996a267474f375a4f94"><span><div id="ccbefbd0b9e34996a267474f375a4f94" class="notion-header-anchor"></div><a class="notion-hash-link" href="#ccbefbd0b9e34996a267474f375a4f94" title="8. 参考资料"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">8. 参考资料</span></span></h3><ul class="notion-list notion-list-disc notion-block-6e81b514996a4b72ab756eeb356802cc"><li><a class="notion-link" href="https://www.intel.com/content/www/us/en/developer/articles/technical/intel-sdm.html" target="_blank" rel="noopener noreferrer">Intel 64 and IA-32 Architectures Software Developer Manuals</a></li></ul><ul class="notion-list notion-list-disc notion-block-31ce16385ac947deb9765403644f666f"><li><a class="notion-link" href="https://www.amd.com/en/search/documentation/hub.html" target="_blank" rel="noopener noreferrer">AMD64 Architecture Programmer’s Manual</a></li></ul><ul class="notion-list notion-list-disc notion-block-399560c488bc80ebbd95ebfbcec37002"><li><a class="notion-link" href="https://www.zhihu.com/question/348237008/answer/843382847" target="_blank" rel="noopener noreferrer">CPU 是怎么认识代码的？</a></li></ul><ul class="notion-list notion-list-disc notion-block-399560c488bc80e09f10ee9388aad08d"><li><a class="notion-link" href="https://www.cnblogs.com/wujianming-110117/p/15729769.html" target="_blank" rel="noopener noreferrer">CPU 内部结构解析</a></li></ul></main></div>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Git 与 SVN ]]></title>
            <link>https://www.yyshow.xyz/article/version-control-git-svn</link>
            <guid>https://www.yyshow.xyz/article/version-control-git-svn</guid>
            <pubDate>Mon, 22 Dec 2025 00:00:00 GMT</pubDate>
            <description><![CDATA[整理 Git 与 SVN 的核心模型、常用命令、分支和远程协作、撤销操作、冲突处理、.gitignore，以及游戏项目中的选型。]]></description>
            <content:encoded><![CDATA[<div id="notion-article" class="mx-auto overflow-hidden "><main class="notion light-mode notion-page notion-block-399560c488bc81a9a1ffdb5ae3dcf80c"><div class="notion-viewport"></div><div class="notion-collection-page-properties"></div><div class="notion-blank notion-block-18f3b8a484594b2095acc87a03853bdd"> </div><blockquote class="notion-quote notion-block-b3f1a92a4fd54b39aedc13a8cab91517"><div>本文重点说明了 Git 的工作区、暂存区、本地仓库和远程仓库，以及 Git 与 SVN 的协作模型。</div></blockquote><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-0c3cc8d8eba14765b64cd5f11db022cd" data-id="0c3cc8d8eba14765b64cd5f11db022cd"><span><div id="0c3cc8d8eba14765b64cd5f11db022cd" class="notion-header-anchor"></div><a class="notion-hash-link" href="#0c3cc8d8eba14765b64cd5f11db022cd" title="1. 版本控制解决什么问题"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">1. 版本控制解决什么问题</span></span></h3><div class="notion-text notion-block-f107304218af4dc7aaf4f7f42bf51722">版本控制系统（VCS）用于记录文件随时间发生的变化，使开发者能够：</div><ul class="notion-list notion-list-disc notion-block-ffb18f6d53304603903eeedbba58da85"><li>查看谁在什么时间修改了哪些内容；</li></ul><ul class="notion-list notion-list-disc notion-block-42af7026cb954d939f03244fa02f3064"><li>对比两个版本之间的差异；</li></ul><ul class="notion-list notion-list-disc notion-block-aaa56418b4a1418c87eeec56b07b7439"><li>恢复到历史版本；</li></ul><ul class="notion-list notion-list-disc notion-block-fbb736f118b14479b56af1e5ea2e8ab5"><li>让多人并行开发并合并修改；</li></ul><ul class="notion-list notion-list-disc notion-block-31f22dc80b6b40ac81f358f534f1a52d"><li>通过分支隔离功能开发、修复和发布工作。</li></ul><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-84a693d4987a4d46966fed4e677e887b" data-id="84a693d4987a4d46966fed4e677e887b"><span><div id="84a693d4987a4d46966fed4e677e887b" class="notion-header-anchor"></div><a class="notion-hash-link" href="#84a693d4987a4d46966fed4e677e887b" title="2. Git 的基本模型"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">2. Git 的基本模型</span></span></h3><div class="notion-text notion-block-3d583de679f74ce9b721bc4b6d7225ac">Git 是分布式版本控制系统。每次正常克隆都会得到项目历史和对象数据库的本地副本，因此大多数查看历史、创建分支、提交等操作可以离线完成。</div><div class="notion-text notion-block-53a5ce4d2871417fbebb06f330ffa86f">Git 日常使用涉及四个位置：</div><ol start="1" class="notion-list notion-list-numbered notion-block-00bf5a1808884d96af72ce1e43245062" style="list-style-type:decimal"><li><b>工作区（Working Tree）</b>：正在编辑的实际文件。</li></ol><ol start="2" class="notion-list notion-list-numbered notion-block-ea899025e03d44dca81795a7f913742a" style="list-style-type:decimal"><li><b>暂存区（Index / Staging Area）</b>：下一次提交准备包含的快照。</li></ol><ol start="3" class="notion-list notion-list-numbered notion-block-0540c388eb954f5b8ef7b18d8b57d217" style="list-style-type:decimal"><li><b>本地仓库（Local Repository）</b>：已经创建的提交历史。</li></ol><ol start="4" class="notion-list notion-list-numbered notion-block-5534196c057649c29451a3cc342f8af3" style="list-style-type:decimal"><li><b>远程仓库（Remote Repository）</b>：GitHub、GitLab 或公司服务器上的共享仓库。</li></ol><div class="notion-text notion-block-d3fe7e69c2b04a34a5a31f7d35439811">典型数据流：</div><div class="notion-text notion-block-3823142feb334198a8002059bdef586e">从远程获取数据：</div><blockquote class="notion-quote notion-block-29ad5c90a4564953b27261fa2c568d47"><div>Git 并不要求“每次修改前必须先同步”。但团队开发时，在开始工作或推送前获取远程最新状态，可以减少冲突。</div></blockquote><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-ddf77369261849f68c11ce8431a38868" data-id="ddf77369261849f68c11ce8431a38868"><span><div id="ddf77369261849f68c11ce8431a38868" class="notion-header-anchor"></div><a class="notion-hash-link" href="#ddf77369261849f68c11ce8431a38868" title="3. Git 的三种使用方式"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">3. Git 的三种使用方式</span></span></h3><ul class="notion-list notion-list-disc notion-block-fdb50812ed6a4f60852c4e52795da72b"><li><b>命令行 CLI</b>：Git Bash、PowerShell、Terminal。</li></ul><ul class="notion-list notion-list-disc notion-block-c559bbb11645478899e334370d543750"><li><b>图形界面 GUI</b>：Fork、SourceTree、GitKraken 等。</li></ul><ul class="notion-list notion-list-disc notion-block-24279d2efcb24c8f93a21e7932f79111"><li><b>IDE 集成</b>：Visual Studio、VS Code、JetBrains Rider 等。</li></ul><div class="notion-text notion-block-b1c8495b52f34d65bdce5408ce2395c3">GUI 不是 CUI。CUI 通常指字符用户界面，GUI 指图形用户界面。</div><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-d73361ae56b4409db92e41444bdcd94a" data-id="d73361ae56b4409db92e41444bdcd94a"><span><div id="d73361ae56b4409db92e41444bdcd94a" class="notion-header-anchor"></div><a class="notion-hash-link" href="#d73361ae56b4409db92e41444bdcd94a" title="4. 常用命令分类"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">4. 常用命令分类</span></span></h3><div class="notion-text notion-block-35394d5fdad44c0ab50daf3ced9003c6">本章从「初始化和克隆」「查看状态和差异」和「暂存和提交」等方面说明常用命令分类。</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-ebdcaabdd4084df3ab7bf282f060659b" data-id="ebdcaabdd4084df3ab7bf282f060659b"><span><div id="ebdcaabdd4084df3ab7bf282f060659b" class="notion-header-anchor"></div><a class="notion-hash-link" href="#ebdcaabdd4084df3ab7bf282f060659b" title="4.1 初始化和克隆"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">4.1 初始化和克隆</span></span></h4><div class="notion-text notion-block-31c2103b36764c779e2ba99cc6a6b94c"><code class="notion-inline-code">git init</code> 将当前目录初始化为 Git 仓库；<code class="notion-inline-code">git clone</code> 会复制远程仓库并自动设置默认远程名 <code class="notion-inline-code">origin</code>。</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-8978e46ad4b441b39a877d9c47a82487" data-id="8978e46ad4b441b39a877d9c47a82487"><span><div id="8978e46ad4b441b39a877d9c47a82487" class="notion-header-anchor"></div><a class="notion-hash-link" href="#8978e46ad4b441b39a877d9c47a82487" title="4.2 查看状态和差异"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">4.2 查看状态和差异</span></span></h4><ul class="notion-list notion-list-disc notion-block-48c8e441acc64d7a99fbe0276ebd4a5b"><li><code class="notion-inline-code">git diff</code>：工作区与暂存区之间的差异。</li></ul><ul class="notion-list notion-list-disc notion-block-d3dbebd31bf24a6eb68d33c7bec89126"><li><code class="notion-inline-code">git diff --staged</code>：暂存区与当前提交之间的差异。</li></ul><ul class="notion-list notion-list-disc notion-block-f7d4e3f3dd43473e9f4d25ca313c725b"><li><code class="notion-inline-code">git log</code>：查看提交历史。</li></ul><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-6dae9c417f174999b2f055c442274cd2" data-id="6dae9c417f174999b2f055c442274cd2"><span><div id="6dae9c417f174999b2f055c442274cd2" class="notion-header-anchor"></div><a class="notion-hash-link" href="#6dae9c417f174999b2f055c442274cd2" title="4.3 暂存和提交"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">4.3 暂存和提交</span></span></h4><div class="notion-text notion-block-c92afcb26e6c49bb9cac457bff4c8d00"><code class="notion-inline-code">git commit -a -m &quot;...&quot;</code> 只会自动暂存<b>已经被 Git 跟踪的文件</b>的修改和删除，不会自动加入新建的未跟踪文件。</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-ade12a59895641d0b35ebedc9bd75ea2" data-id="ade12a59895641d0b35ebedc9bd75ea2"><span><div id="ade12a59895641d0b35ebedc9bd75ea2" class="notion-header-anchor"></div><a class="notion-hash-link" href="#ade12a59895641d0b35ebedc9bd75ea2" title="4.4 删除和重命名"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">4.4 删除和重命名</span></span></h4><div class="notion-text notion-block-76b4e46a2d054dcbbadddf90d8e43ecd">直接在文件管理器中删除或重命名也可以，但之后仍需使用 <code class="notion-inline-code">git add -A</code> 记录变化。</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-e1f0e0270c434e4eb4ae2393269d39c0" data-id="e1f0e0270c434e4eb4ae2393269d39c0"><span><div id="e1f0e0270c434e4eb4ae2393269d39c0" class="notion-header-anchor"></div><a class="notion-hash-link" href="#e1f0e0270c434e4eb4ae2393269d39c0" title="4.5 远程仓库"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">4.5 远程仓库</span></span></h4><div class="notion-text notion-block-d6cc552cb3f24ba7862b3998a4ed73a7">当前新仓库通常使用 <code class="notion-inline-code">main</code> 作为默认分支，但实际名称应通过 <code class="notion-inline-code">git branch --show-current</code> 确认，不能固定假设为 <code class="notion-inline-code">master</code>。</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-fff78aeb3c74462291e553c6662e8a7f" data-id="fff78aeb3c74462291e553c6662e8a7f"><span><div id="fff78aeb3c74462291e553c6662e8a7f" class="notion-header-anchor"></div><a class="notion-hash-link" href="#fff78aeb3c74462291e553c6662e8a7f" title="4.6 分支"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">4.6 分支</span></span></h4><div class="notion-text notion-block-ed257f1b844f4aab880108e3520d2ba4"><code class="notion-inline-code">git checkout</code> 仍然可用，但现代 Git 将常见职责拆分为：</div><ul class="notion-list notion-list-disc notion-block-dd66ee48643b451cbdb7945eec1c0480"><li><code class="notion-inline-code">git switch</code>：切换或创建分支；</li></ul><ul class="notion-list notion-list-disc notion-block-704010f9359e41e8a1ba0761f9bd23f2"><li><code class="notion-inline-code">git restore</code>：恢复文件；</li></ul><ul class="notion-list notion-list-disc notion-block-9a27bc710a914d1fbe1f0e873235042e"><li><code class="notion-inline-code">git checkout</code>：兼容旧用法，也可处理更多低层场景。</li></ul><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-9ed9e12f0a6f45f4899e0d39060c8407" data-id="9ed9e12f0a6f45f4899e0d39060c8407"><span><div id="9ed9e12f0a6f45f4899e0d39060c8407" class="notion-header-anchor"></div><a class="notion-hash-link" href="#9ed9e12f0a6f45f4899e0d39060c8407" title="4.7 标签"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">4.7 标签</span></span></h4><div class="notion-text notion-block-8b9b4f3c957b4c708043780877b56a99">正确的批量推送参数是 <code class="notion-inline-code">--tags</code>，不是 <code class="notion-inline-code">--tag</code>。</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-1f7f6353c0344562b0fbb8c5915a6aaa" data-id="1f7f6353c0344562b0fbb8c5915a6aaa"><span><div id="1f7f6353c0344562b0fbb8c5915a6aaa" class="notion-header-anchor"></div><a class="notion-hash-link" href="#1f7f6353c0344562b0fbb8c5915a6aaa" title="4.8 临时保存"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">4.8 临时保存</span></span></h4><div class="notion-text notion-block-2cb22f4e90cc44dd85c3d2ac491efc24"><code class="notion-inline-code">stash</code> 适合暂时切换任务，不应代替正常提交和分支。</div><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-729f1f8c4f8d4d2fb353ad1260a3e03e" data-id="729f1f8c4f8d4d2fb353ad1260a3e03e"><span><div id="729f1f8c4f8d4d2fb353ad1260a3e03e" class="notion-header-anchor"></div><a class="notion-hash-link" href="#729f1f8c4f8d4d2fb353ad1260a3e03e" title="5. 撤销操作：restore、reset、revert"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">5. 撤销操作：restore、reset、revert</span></span></h3><div class="notion-text notion-block-9119a93f1b0949a7b959cc3957d3c251">这是 Git 最容易混淆的部分。</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-38944302386b4560905161c8c0a84fd9" data-id="38944302386b4560905161c8c0a84fd9"><span><div id="38944302386b4560905161c8c0a84fd9" class="notion-header-anchor"></div><a class="notion-hash-link" href="#38944302386b4560905161c8c0a84fd9" title="5.1 git restore"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">5.1 <code class="notion-inline-code">git restore</code></span></span></h4><div class="notion-text notion-block-4cb6445fac6f43f5b585ee5678ad2132">用于恢复工作区文件或取消暂存：</div><div class="notion-text notion-block-ed688f6c0c72463a8ba231f2709cec4b">第一条会丢失未提交修改，执行前应确认。</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-b30b524f3dd3495eb55fb46547cf8e1c" data-id="b30b524f3dd3495eb55fb46547cf8e1c"><span><div id="b30b524f3dd3495eb55fb46547cf8e1c" class="notion-header-anchor"></div><a class="notion-hash-link" href="#b30b524f3dd3495eb55fb46547cf8e1c" title="5.2 git reset"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">5.2 <code class="notion-inline-code">git reset</code></span></span></h4><div class="notion-text notion-block-27595e86aa3941bbb3425419a0478686"><code class="notion-inline-code">reset</code> 可以移动当前分支的 <code class="notion-inline-code">HEAD</code>，并根据模式影响暂存区和工作区：</div><ul class="notion-list notion-list-disc notion-block-70bf79372a6d41a0a36e91f09a1b634c"><li><code class="notion-inline-code">--soft</code>：只移动 <code class="notion-inline-code">HEAD</code>，保留暂存区和工作区。</li></ul><ul class="notion-list notion-list-disc notion-block-ff6a88547ca1492fa3dc5f96ed63aa38"><li><code class="notion-inline-code">--mixed</code>：移动 <code class="notion-inline-code">HEAD</code> 并重置暂存区，保留工作区；这是默认模式。</li></ul><ul class="notion-list notion-list-disc notion-block-9086b3f974d94e82b44471d1851c01d8"><li><code class="notion-inline-code">--hard</code>：同时重置 <code class="notion-inline-code">HEAD</code>、暂存区和工作区，可能永久丢失未提交修改。</li></ul><div class="notion-text notion-block-8179c5c6899f434b825045a4bed6df63"><code class="notion-inline-code">git reset --hard</code> 不应随意用于已经推送并被他人使用的共享历史。</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-155bae3cf7174813ad66274d07605227" data-id="155bae3cf7174813ad66274d07605227"><span><div id="155bae3cf7174813ad66274d07605227" class="notion-header-anchor"></div><a class="notion-hash-link" href="#155bae3cf7174813ad66274d07605227" title="5.3 git revert"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">5.3 <code class="notion-inline-code">git revert</code></span></span></h4><div class="notion-text notion-block-541d9fd1251944d4aef8bc888f30d75b"><code class="notion-inline-code">revert</code> 不改写已有历史，而是创建一个新的“反向提交”。对已经推送的公共分支，通常优先使用 <code class="notion-inline-code">revert</code>。</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-e0555bd89a434c1698997f4a0afe2891" data-id="e0555bd89a434c1698997f4a0afe2891"><span><div id="e0555bd89a434c1698997f4a0afe2891" class="notion-header-anchor"></div><a class="notion-hash-link" href="#e0555bd89a434c1698997f4a0afe2891" title="5.4 恢复误删提交"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">5.4 恢复误删提交</span></span></h4><div class="notion-text notion-block-60e300142b5940f39b960beb80299f69">只要对象尚未被垃圾回收，<code class="notion-inline-code">reflog</code> 经常可以找回本地误操作前的提交。</div><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-be415df32794448285e3b352c37ff86b" data-id="be415df32794448285e3b352c37ff86b"><span><div id="be415df32794448285e3b352c37ff86b" class="notion-header-anchor"></div><a class="notion-hash-link" href="#be415df32794448285e3b352c37ff86b" title="6. .gitignore"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">6. <code class="notion-inline-code">.gitignore</code></span></span></h3><div class="notion-text notion-block-c0aa9fd3ba0c44a28074116ff137e353"><code class="notion-inline-code">.gitignore</code> 用来忽略不应进入仓库的文件，例如：</div><ul class="notion-list notion-list-disc notion-block-867d8b53e98b408fb121e4f9c948a117"><li>编译输出；</li></ul><ul class="notion-list notion-list-disc notion-block-9a8186dad6cf4843a000a7e5c9a7aa01"><li>临时缓存；</li></ul><ul class="notion-list notion-list-disc notion-block-a8716634a4a243e78da91b8204f9d42f"><li>IDE 本地设置；</li></ul><ul class="notion-list notion-list-disc notion-block-20749004a2a24b5592a70e9af625aef7"><li>密钥和环境变量；</li></ul><ul class="notion-list notion-list-disc notion-block-b308d57dd8cf4acb8d8e0d14bd0be28b"><li>Unity 的 <code class="notion-inline-code">Library/</code>、<code class="notion-inline-code">Temp/</code>、<code class="notion-inline-code">Logs/</code> 等可再生成目录。</li></ul><div class="notion-text notion-block-bbc43c60761241be8d2da11c99525d0f">注意：</div><ul class="notion-list notion-list-disc notion-block-6c0bc4acfeac42ee9cd76d1d0f869f7c"><li><code class="notion-inline-code">.gitignore</code> 只影响尚未被跟踪的文件；</li></ul><ul class="notion-list notion-list-disc notion-block-089f40936fab446580cffb06782263d3"><li>已经提交过的文件不会因为后来加入忽略规则就自动停止跟踪；</li></ul><ul class="notion-list notion-list-disc notion-block-b434a851e7024ea592ab13afd32a201e"><li>可使用 <code class="notion-inline-code">git check-ignore -v &lt;文件&gt;</code> 排查匹配了哪条规则。</li></ul><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-44b17cac1e3e43b993e783e9c5e32df8" data-id="44b17cac1e3e43b993e783e9c5e32df8"><span><div id="44b17cac1e3e43b993e783e9c5e32df8" class="notion-header-anchor"></div><a class="notion-hash-link" href="#44b17cac1e3e43b993e783e9c5e32df8" title="7. 冲突处理"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">7. 冲突处理</span></span></h3><div class="notion-text notion-block-87777d60e6f740a29f7ecfdac9edbf99">冲突通常发生在两条开发线修改了相同文件的相同区域时。</div><div class="notion-text notion-block-2f30cb58f3254eb5b7091ca9e5fe7395">基本流程：</div><div class="notion-text notion-block-5a1f9341226f4651b25916181f6afe48">常见冲突标记：</div><div class="notion-text notion-block-cdea5dd332f9465db7ebcda5188021af">版本控制系统只能帮助标出文本冲突，业务语义是否正确仍需开发者判断。</div><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-3a694132c3b7477db3da8b6acdfe98bf" data-id="3a694132c3b7477db3da8b6acdfe98bf"><span><div id="3a694132c3b7477db3da8b6acdfe98bf" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3a694132c3b7477db3da8b6acdfe98bf" title="8. SVN 的基本模型"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">8. SVN 的基本模型</span></span></h3><div class="notion-text notion-block-d96f29fcf71a4c338ea808285d0a6f87">SVN 是集中式版本控制系统。版本历史的权威副本位于中央仓库，开发者在本地使用工作副本。</div><div class="notion-text notion-block-0c88122e329e4693a06828973a8fad5b">常见流程：</div><div class="notion-text notion-block-76a62397c8d34eb2a56e841a2d515def">准确理解：</div><ul class="notion-list notion-list-disc notion-block-5762b42b54774236a03f45e45a01f3d6"><li>即使中央服务器不可用，开发者通常仍能编辑本地工作副本；</li></ul><ul class="notion-list notion-list-disc notion-block-351d89c43c4c46ad9656ac8aabefe944"><li>但无法更新、提交或访问完整中央历史；</li></ul><ul class="notion-list notion-list-disc notion-block-d582c78c33304c629c70ae2483c88eda"><li>SVN 默认也支持“复制—修改—合并”模型，并不是所有文件都必须加锁；</li></ul><ul class="notion-list notion-list-disc notion-block-bde41b2360cd44a4ab3e6c0e2db17736"><li>对 PSD、音频、场景二进制文件等难以合并的资源，可以使用锁机制避免多人同时修改。</li></ul><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-e1b47257dd854f8ba0a239a8a48faae9" data-id="e1b47257dd854f8ba0a239a8a48faae9"><span><div id="e1b47257dd854f8ba0a239a8a48faae9" class="notion-header-anchor"></div><a class="notion-hash-link" href="#e1b47257dd854f8ba0a239a8a48faae9" title="9. Git 与 SVN 对比"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">9. Git 与 SVN 对比</span></span></h3><div class="notion-text notion-block-999a398e3f4d463b8779ce4503379fbc">本章从「Git」和「SVN」两方面说明 Git 与 SVN 对比。</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-4edfc1d45f4c4f9eb60c7123495a7b0a" data-id="4edfc1d45f4c4f9eb60c7123495a7b0a"><span><div id="4edfc1d45f4c4f9eb60c7123495a7b0a" class="notion-header-anchor"></div><a class="notion-hash-link" href="#4edfc1d45f4c4f9eb60c7123495a7b0a" title="9.1 Git"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">9.1 Git</span></span></h4><ul class="notion-list notion-list-disc notion-block-1800bce3b6604cc8971df9936aaad9e4"><li>分布式，本地仓库包含历史；</li></ul><ul class="notion-list notion-list-disc notion-block-3ff6be6d1fc2439b80f5243dad5b6b75"><li>本地提交、分支和查看历史速度快；</li></ul><ul class="notion-list notion-list-disc notion-block-c0f34dcfe67446d1a4d4a8932e601ae2"><li>分支成本低，适合并行功能开发；</li></ul><ul class="notion-list notion-list-disc notion-block-4b2684afbcb647889b0fc6b058d88c65"><li>离线可完成多数操作；</li></ul><ul class="notion-list notion-list-disc notion-block-8f04ec316714475d801b9f46a724c0b7"><li>学习成本相对更高；</li></ul><ul class="notion-list notion-list-disc notion-block-cc14007b3549421d8e2de297dca18440"><li>大型二进制资源需要 Git LFS 等补充方案。</li></ul><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-6460eb891e1340cd9f4d0b165225a467" data-id="6460eb891e1340cd9f4d0b165225a467"><span><div id="6460eb891e1340cd9f4d0b165225a467" class="notion-header-anchor"></div><a class="notion-hash-link" href="#6460eb891e1340cd9f4d0b165225a467" title="9.2 SVN"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">9.2 SVN</span></span></h4><ul class="notion-list notion-list-disc notion-block-e6f23556dc8f44ae928e7bce1beb9586"><li>集中式，中央仓库是权威历史；</li></ul><ul class="notion-list notion-list-disc notion-block-ec0e763e311347b18e6b6cbe68292526"><li>权限和目录级管理直观；</li></ul><ul class="notion-list notion-list-disc notion-block-261ff94c96564931b7357847e262e18a"><li>工作副本操作模型较简单；</li></ul><ul class="notion-list notion-list-disc notion-block-b5b7ce9055d24d9a83f0f1c216c6621c"><li>对需要锁定的二进制美术资源较友好；</li></ul><ul class="notion-list notion-list-disc notion-block-529514073ac5496b9b9070bca4a77f7a"><li>网络或中央服务故障会阻断更新和提交；</li></ul><ul class="notion-list notion-list-disc notion-block-b4fcfcc516114f76942ab106d21dc624"><li>分支通常通过目录复制实现，使用习惯与 Git 不同。</li></ul><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-1df2909534ba46acbcacddd5e0d20798" data-id="1df2909534ba46acbcacddd5e0d20798"><span><div id="1df2909534ba46acbcacddd5e0d20798" class="notion-header-anchor"></div><a class="notion-hash-link" href="#1df2909534ba46acbcacddd5e0d20798" title="10. 游戏项目中的选型建议"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">10. 游戏项目中的选型建议</span></span></h3><div class="notion-text notion-block-2af4bfab0ec648139aa12da5e57758ed">本章从「代码为主的小型项目」和「美术资源很多的集中式流程」两方面说明游戏项目中的选型建议。</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-70c9472a5fd94eb1bad8a1125b55ee19" data-id="70c9472a5fd94eb1bad8a1125b55ee19"><span><div id="70c9472a5fd94eb1bad8a1125b55ee19" class="notion-header-anchor"></div><a class="notion-hash-link" href="#70c9472a5fd94eb1bad8a1125b55ee19" title="10.1 代码为主的小型项目"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">10.1 代码为主的小型项目</span></span></h4><div class="notion-text notion-block-7fb90dc5a5c1446aa12c390eef01022b">优先考虑 Git：</div><ul class="notion-list notion-list-disc notion-block-7540564c55c24b17bb1b36d4d8273538"><li>使用功能分支；</li></ul><ul class="notion-list notion-list-disc notion-block-5dcdc31819154d0180f89ec63415ca67"><li>代码评审通过 Pull Request；</li></ul><ul class="notion-list notion-list-disc notion-block-4d81130373a34b7ea309f8c6cb55bb07"><li>将可再生成目录加入 <code class="notion-inline-code">.gitignore</code>；</li></ul><ul class="notion-list notion-list-disc notion-block-ccf921ecfb574487884ebf8c3a3020e1"><li>大文件使用 Git LFS。</li></ul><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-ec72ec98855d435991ed92990c848235" data-id="ec72ec98855d435991ed92990c848235"><span><div id="ec72ec98855d435991ed92990c848235" class="notion-header-anchor"></div><a class="notion-hash-link" href="#ec72ec98855d435991ed92990c848235" title="10.2 美术资源很多的集中式流程"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">10.2 美术资源很多的集中式流程</span></span></h4><div class="notion-text notion-block-be6f887be8db47e09dbd92529775a86b">SVN 或其他集中式资产管理工具仍可能更适合：</div><ul class="notion-list notion-list-disc notion-block-c18a61d1b43a404cac3be7576e7f11d2"><li>对不可合并文件设置锁；</li></ul><ul class="notion-list notion-list-disc notion-block-510d5bb881574fdf95ae54afe69f0b36"><li>规定场景、Prefab 和大资源的负责人；</li></ul><ul class="notion-list notion-list-disc notion-block-612473a2d3c04971857eb8d929861cde"><li>提交前先更新并解决冲突；</li></ul><ul class="notion-list notion-list-disc notion-block-8ef0f613ca7a4e7e9449af30b4b3da35"><li>将代码评审和资源审批流程分开。</li></ul><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-d7b336bae1a442008ab41888e47399f7" data-id="d7b336bae1a442008ab41888e47399f7"><span><div id="d7b336bae1a442008ab41888e47399f7" class="notion-header-anchor"></div><a class="notion-hash-link" href="#d7b336bae1a442008ab41888e47399f7" title="11. 总结"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">11. 总结</span></span></h3><div class="notion-text notion-block-ad0a12ad5a524e1dba2e61987b8c1c76">Git 适合以本地提交、分支和合并为核心的分布式协作；SVN 适合强调集中权限、目录级管理和统一主线的流程。选型时应结合资产类型、团队规模、网络环境和发布方式，而不是只比较命令数量。</div><div class="notion-text notion-block-cacbddee26cf4df4bb310ad1e782c08c">无论使用哪种工具，都要先确认工作区状态和变更范围，再执行提交、回退或冲突处理。</div><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-49ae8589ab484288b8005d4b8dbc30af" data-id="49ae8589ab484288b8005d4b8dbc30af"><span><div id="49ae8589ab484288b8005d4b8dbc30af" class="notion-header-anchor"></div><a class="notion-hash-link" href="#49ae8589ab484288b8005d4b8dbc30af" title="12. 官方参考"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">12. 官方参考</span></span></h3><ul class="notion-list notion-list-disc notion-block-266a655f64534ee299a20dd06f67d4da"><li><a class="notion-link" href="https://git-scm.com/docs" target="_blank" rel="noopener noreferrer">Git 官方参考手册</a></li></ul><ul class="notion-list notion-list-disc notion-block-b722278786344103900e55cd69075a6d"><li><a class="notion-link" href="https://git-scm.com/book/" target="_blank" rel="noopener noreferrer">Pro Git 在线书</a></li></ul><ul class="notion-list notion-list-disc notion-block-498e536ea5a2408d939bc888a518f0a5"><li><a class="notion-link" href="https://git-scm.com/docs/git-reset" target="_blank" rel="noopener noreferrer">Git reset 文档</a></li></ul><ul class="notion-list notion-list-disc notion-block-a3b4aef8d39243079e0242555814106f"><li><a class="notion-link" href="https://git-scm.com/docs/git-restore" target="_blank" rel="noopener noreferrer">Git restore 文档</a></li></ul><ul class="notion-list notion-list-disc notion-block-4e45eb0b841b4dd5b7e8195412b977a9"><li><a class="notion-link" href="https://svnbook.red-bean.com/" target="_blank" rel="noopener noreferrer">Version Control with Subversion</a></li></ul></main></div>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[TypeScript 学习笔记]]></title>
            <link>https://www.yyshow.xyz/article/typescript-study-notes</link>
            <guid>https://www.yyshow.xyz/article/typescript-study-notes</guid>
            <pubDate>Sun, 05 Jul 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[系统整理 TypeScript 类型系统、泛型、工具类型、类、声明文件、模块导入与路径解析，以及 Cocos Creator 实践与常见误区。]]></description>
            <content:encoded><![CDATA[<div id="notion-article" class="mx-auto overflow-hidden "><main class="notion light-mode notion-page notion-block-399560c488bc81edb063f96c5671c227"><div class="notion-viewport"></div><div class="notion-collection-page-properties"></div><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-de94e68247764f36b15d44874b7a163d" data-id="de94e68247764f36b15d44874b7a163d"><span><div id="de94e68247764f36b15d44874b7a163d" class="notion-header-anchor"></div><a class="notion-hash-link" href="#de94e68247764f36b15d44874b7a163d" title="1. TypeScript 概述"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">1. TypeScript 概述</span></span></h3><div class="notion-text notion-block-e25679ce64ce4495a500cd53b9240e7b">TypeScript 是 JavaScript 的超集，在 JavaScript 的基础上增加了静态类型系统。</div><div class="notion-text notion-block-cade759c1a0a43cca6161bb782291ebd">它并不会取代 JavaScript，而是在代码编译阶段帮助开发者提前发现一部分类型错误，最后仍然会被编译成 JavaScript 运行。</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-5e96a129ee534355afd64c314612e567" data-id="5e96a129ee534355afd64c314612e567"><span><div id="5e96a129ee534355afd64c314612e567" class="notion-header-anchor"></div><a class="notion-hash-link" href="#5e96a129ee534355afd64c314612e567" title="1.1 TypeScript 的优点"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">1.1 TypeScript 的优点</span></span></h4><ul class="notion-list notion-list-disc notion-block-b9f922d3807746148c2d29092aa5c8b1"><li>编译阶段可以发现部分类型错误；</li></ul><ul class="notion-list notion-list-disc notion-block-b64422c4a4f5485ba179b1e788595f58"><li>IDE 的代码提示、跳转和重构能力更强；</li></ul><ul class="notion-list notion-list-disc notion-block-dcac70e368e04738a975cdc95aa09eea"><li>函数参数、返回值和数据结构更清晰；</li></ul><ul class="notion-list notion-list-disc notion-block-94bccf25573c45989228e0e3dff695e8"><li>大型项目和多人协作时更容易维护；</li></ul><ul class="notion-list notion-list-disc notion-block-e069e44f9ebb46a6ab2faeb4d4f300a0"><li>修改接口或重构代码时更加安全。</li></ul><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-4ce48ee8c6b348c48e619fec693eee5a" data-id="4ce48ee8c6b348c48e619fec693eee5a"><span><div id="4ce48ee8c6b348c48e619fec693eee5a" class="notion-header-anchor"></div><a class="notion-hash-link" href="#4ce48ee8c6b348c48e619fec693eee5a" title="1.2 TypeScript 的缺点"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">1.2 TypeScript 的缺点</span></span></h4><ul class="notion-list notion-list-disc notion-block-63b42894624f40d89d383e856138cda1"><li>需要额外学习类型系统；</li></ul><ul class="notion-list notion-list-disc notion-block-b2acb8c04fa243e5a6481a7d90d5473e"><li>类型写得过于复杂时，可读性可能下降；</li></ul><ul class="notion-list notion-list-disc notion-block-0d06a3096262432a8da2dd664725ade5"><li>第三方库缺少类型声明时，需要自己补充 <code class="notion-inline-code">.d.ts</code> 文件；</li></ul><ul class="notion-list notion-list-disc notion-block-dadab48218f04e11ae3bd6b0b3eb877d"><li>如果项目中大量使用 <code class="notion-inline-code">any</code>，类型系统会逐渐失去意义。</li></ul><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-b0be81044fb149c8945b463ebd00b824" data-id="b0be81044fb149c8945b463ebd00b824"><span><div id="b0be81044fb149c8945b463ebd00b824" class="notion-header-anchor"></div><a class="notion-hash-link" href="#b0be81044fb149c8945b463ebd00b824" title="1.3 适用场景"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">1.3 适用场景</span></span></h4><div class="notion-text notion-block-f81e1289a961494a898d522b0bf8681a">TypeScript 比较适合：</div><ul class="notion-list notion-list-disc notion-block-88e1576ef174468d8dd45f583d09cc59"><li>大型项目；</li></ul><ul class="notion-list notion-list-disc notion-block-111cc955200a4cabbadf87bbfc6be1df"><li>多人协作项目；</li></ul><ul class="notion-list notion-list-disc notion-block-13124a4ec8e244239facf1d3a3353d35"><li>接口和数据结构较复杂的项目；</li></ul><ul class="notion-list notion-list-disc notion-block-6fdda950ec754836b27f9860de570bfe"><li>前端工程化项目；</li></ul><ul class="notion-list notion-list-disc notion-block-8868211f767c4baeb4bf5c0b01d8dc2c"><li>Cocos Creator 游戏客户端项目；</li></ul><ul class="notion-list notion-list-disc notion-block-df1ec76bff724841b4939d06ad9bbf77"><li>需要长期维护和频繁重构的项目。</li></ul><blockquote class="notion-quote notion-block-52c51db39ac441e899cb64cea31be084"><div>在 Cocos Creator 项目中，TypeScript 可以明确描述 <code class="notion-inline-code">Node</code>、<code class="notion-inline-code">Button</code>、<code class="notion-inline-code">Label</code>、资源对象、商品数据、关卡配置等类型，减少组件获取和数据传递时的错误。</div></blockquote><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-9dff108e7ddd482583c251a294e36049" data-id="9dff108e7ddd482583c251a294e36049"><span><div id="9dff108e7ddd482583c251a294e36049" class="notion-header-anchor"></div><a class="notion-hash-link" href="#9dff108e7ddd482583c251a294e36049" title="2. TypeScript 基础类型"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">2. TypeScript 基础类型</span></span></h3><div class="notion-text notion-block-dc1b8f5a876d422e83603e15998e0536">TypeScript 中常见的基础类型包括：</div><div class="notion-text notion-block-3b93a8ab35c24942ad5f2a025cd0172e">JavaScript 原有的基础值类型包括：</div><ul class="notion-list notion-list-disc notion-block-3f5c5609eac24549b5a21fd477a4847d"><li><code class="notion-inline-code">string</code></li></ul><ul class="notion-list notion-list-disc notion-block-b03c4ad2bda64b50a9bbe706df67e786"><li><code class="notion-inline-code">number</code></li></ul><ul class="notion-list notion-list-disc notion-block-4e8f5ce81e2645e192f4f4d6398bcbde"><li><code class="notion-inline-code">boolean</code></li></ul><ul class="notion-list notion-list-disc notion-block-bf4d067a4013438a90168aefcfef30bc"><li><code class="notion-inline-code">null</code></li></ul><ul class="notion-list notion-list-disc notion-block-0588d45d619d418dabd8b846cde5107c"><li><code class="notion-inline-code">undefined</code></li></ul><ul class="notion-list notion-list-disc notion-block-490274bed68e4c6ba5ae1e34ffc4449b"><li><code class="notion-inline-code">symbol</code></li></ul><ul class="notion-list notion-list-disc notion-block-5112b284b73749699ce9200257768f38"><li><code class="notion-inline-code">bigint</code></li></ul><div class="notion-text notion-block-28ed5d087f9940878c321ee013aa9545">TypeScript 在此基础上又提供了：</div><ul class="notion-list notion-list-disc notion-block-6be0942facbb45d9836ab32310067826"><li>数组；</li></ul><ul class="notion-list notion-list-disc notion-block-3f4d22613281486f85ee38b81c304313"><li>元组；</li></ul><ul class="notion-list notion-list-disc notion-block-14a5400da3c043589f441df316b6a2a8"><li>枚举；</li></ul><ul class="notion-list notion-list-disc notion-block-38acb547de144148b1e874a2615379b2"><li>对象类型；</li></ul><ul class="notion-list notion-list-disc notion-block-d1d7095fc01a4225b68f91ab2b977bc2"><li>联合类型；</li></ul><ul class="notion-list notion-list-disc notion-block-fcabcbe3b5b5417582046ee30d66571d"><li>交叉类型；</li></ul><ul class="notion-list notion-list-disc notion-block-ae68b88fc6de4022805f053a07ddd966"><li><code class="notion-inline-code">any</code>；</li></ul><ul class="notion-list notion-list-disc notion-block-4527c9f841a5476e8bcced179c050369"><li><code class="notion-inline-code">unknown</code>；</li></ul><ul class="notion-list notion-list-disc notion-block-5b70c35337a04fff9974902440518234"><li><code class="notion-inline-code">void</code>；</li></ul><ul class="notion-list notion-list-disc notion-block-8046791fab904f28a506ab6ef1c99c88"><li><code class="notion-inline-code">never</code>。</li></ul><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-4ce2cf7eb4d1477692763a2a258fdbd1" data-id="4ce2cf7eb4d1477692763a2a258fdbd1"><span><div id="4ce2cf7eb4d1477692763a2a258fdbd1" class="notion-header-anchor"></div><a class="notion-hash-link" href="#4ce2cf7eb4d1477692763a2a258fdbd1" title="3. 数组与元组"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">3. 数组与元组</span></span></h3><div class="notion-text notion-block-02a83fa7899b4d88a9b74a4e99b59d1a">本章从「Array 数组」和「Tuple 元组」两方面说明数组与元组。</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-fb902586529342d0937b8931e999cd27" data-id="fb902586529342d0937b8931e999cd27"><span><div id="fb902586529342d0937b8931e999cd27" class="notion-header-anchor"></div><a class="notion-hash-link" href="#fb902586529342d0937b8931e999cd27" title="3.1 Array 数组"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">3.1 Array 数组</span></span></h4><div class="notion-text notion-block-743cc52f0a1442e2aa7d966dc3c2f472">数组表示一组数量通常不固定、类型相同或结构相近的数据。</div><div class="notion-text notion-block-c3008823c58e424a8ff9c034cd958288">数组也可以使用联合类型：</div><div class="notion-text notion-block-200771f567314eeea2f60a5640414d8c">所以“数组中的元素只能有一种类型”并不准确，更准确的说法是：数组中的元素必须符合数组声明的元素类型。</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-faac7dfefae3468fa7ad3be470e1577a" data-id="faac7dfefae3468fa7ad3be470e1577a"><span><div id="faac7dfefae3468fa7ad3be470e1577a" class="notion-header-anchor"></div><a class="notion-hash-link" href="#faac7dfefae3468fa7ad3be470e1577a" title="3.2 Tuple 元组"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">3.2 Tuple 元组</span></span></h4><div class="notion-text notion-block-1af4ca3796494649870e743f8d94628e">元组用于表示固定长度、固定位置类型的数据。</div><div class="notion-text notion-block-0158a79b01854d9bbdca133c5416ed9a">其中：</div><ul class="notion-list notion-list-disc notion-block-e8942d5edd114349b3c546f722323db4"><li>第 0 位必须是 <code class="notion-inline-code">string</code>；</li></ul><ul class="notion-list notion-list-disc notion-block-b6528ff982f94335a9790455640a2d52"><li>第 1 位必须是 <code class="notion-inline-code">number</code>。</li></ul><div class="notion-text notion-block-d8d55a9f77d6452ab0b56a482cf792e9">常见使用场景：</div><div class="notion-text notion-block-f5cd46e64d654b78926b5269e26343f7"><code class="notion-inline-code">注意：数组适合表示一组同类数据，元组适合表示固定结构的数据。</code></div><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-87613e2557844c3c99d7a57386156917" data-id="87613e2557844c3c99d7a57386156917"><span><div id="87613e2557844c3c99d7a57386156917" class="notion-header-anchor"></div><a class="notion-hash-link" href="#87613e2557844c3c99d7a57386156917" title="4. 枚举 enum"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">4. 枚举 enum</span></span></h3><div class="notion-text notion-block-7e25be49cdbb47708072978ca566e10d">枚举用于定义一组有限的命名常量。</div><div class="notion-text notion-block-68f95cd5058846de9dce26ca4de3e222">字符串枚举：</div><div class="notion-text notion-block-8a60dbbac0654fea871190e327abe0d5">常见使用场景：</div><ul class="notion-list notion-list-disc notion-block-42258865cbd34a28ada27839826da9bd"><li>游戏状态；</li></ul><ul class="notion-list notion-list-disc notion-block-b8e21f1d37494c9f947ef6c1d4f2eb5d"><li>角色状态；</li></ul><ul class="notion-list notion-list-disc notion-block-5cdee8cbab1e4ed28f4af5efc043dff9"><li>网络消息类型；</li></ul><ul class="notion-list notion-list-disc notion-block-630bc1ff434c4784843b668cf469177e"><li>事件类型；</li></ul><ul class="notion-list notion-list-disc notion-block-252b185122624c9695552bb70e9a8d72"><li>UI 面板类型；</li></ul><ul class="notion-list notion-list-disc notion-block-8b43781f6c274bacbe88b516fd85ef6d"><li>道具类型；</li></ul><ul class="notion-list notion-list-disc notion-block-2e159eb58a6a4e129160fe77d58e956c"><li>动画状态。</li></ul><div class="notion-text notion-block-4a8d8bc5ea4640d29b7384dd36aabe42"><code class="notion-inline-code">注意：enum 编译后通常会生成运行时代码。</code></div><div class="notion-text notion-block-6b3ef3a0f92b42b1bd5c6c36ad2e234b">如果只需要类型约束，也可以使用联合字面量：</div><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-3912b402a7264dedbe9f1a85a6481e3f" data-id="3912b402a7264dedbe9f1a85a6481e3f"><span><div id="3912b402a7264dedbe9f1a85a6481e3f" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3912b402a7264dedbe9f1a85a6481e3f" title="5. keyof、typeof 与 as const"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">5. keyof、typeof 与 as const</span></span></h3><div class="notion-text notion-block-c4fbc6488dc14482b0e2ae4bcb6cec69">本章从「keyof」「typeof」和「keyof typeof」等方面说明 keyof、typeof 与 as const。</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-758adf5a2c294a38b7c2ea3c9e77f7d2" data-id="758adf5a2c294a38b7c2ea3c9e77f7d2"><span><div id="758adf5a2c294a38b7c2ea3c9e77f7d2" class="notion-header-anchor"></div><a class="notion-hash-link" href="#758adf5a2c294a38b7c2ea3c9e77f7d2" title="5.1 keyof"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">5.1 keyof</span></span></h4><div class="notion-text notion-block-2e9b732219144079a73d066eb59f8b26"><code class="notion-inline-code">keyof</code> 用于获取一个对象类型中所有键组成的联合类型。</div><div class="notion-text notion-block-379665c9bcdc4e859a485e2b96439541">常见写法：</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-b9d9fa0ff3f24aaba92269f8c46a0f26" data-id="b9d9fa0ff3f24aaba92269f8c46a0f26"><span><div id="b9d9fa0ff3f24aaba92269f8c46a0f26" class="notion-header-anchor"></div><a class="notion-hash-link" href="#b9d9fa0ff3f24aaba92269f8c46a0f26" title="5.2 typeof"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">5.2 typeof</span></span></h4><div class="notion-text notion-block-59991c35df2246319ed43060ccad8209"><code class="notion-inline-code">typeof</code> 在 JavaScript 和 TypeScript 中有两个不同语境。</div><h5 class="notion-h notion-h4 notion-h-indent-2 notion-block-deb8dfb0ba734c879f0371bd845b7f2f" data-id="deb8dfb0ba734c879f0371bd845b7f2f"><span><div id="deb8dfb0ba734c879f0371bd845b7f2f" class="notion-header-anchor"></div><a class="notion-hash-link" href="#deb8dfb0ba734c879f0371bd845b7f2f" title="5.2.1 JavaScript 运行时"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">5.2.1 JavaScript 运行时</span></span></h5><h5 class="notion-h notion-h4 notion-h-indent-2 notion-block-71594b8f602a4c25939c2ff94106e226" data-id="71594b8f602a4c25939c2ff94106e226"><span><div id="71594b8f602a4c25939c2ff94106e226" class="notion-header-anchor"></div><a class="notion-hash-link" href="#71594b8f602a4c25939c2ff94106e226" title="5.2.2 TypeScript 类型语境"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">5.2.2 TypeScript 类型语境</span></span></h5><div class="notion-text notion-block-8825dbe962de4ae597aba0c28fdbabaa">此时 <code class="notion-inline-code">User</code> 等价于：</div><div class="notion-text notion-block-f7b11e5ad70148aa95c0953ab01541c9">简单理解：</div><ul class="notion-list notion-list-disc notion-block-01f612c846364759bf8ecda88c9829ec"><li><code class="notion-inline-code">keyof</code>：这个类型有哪些字段；</li></ul><ul class="notion-list notion-list-disc notion-block-697da3fbc972407f8dc4acf29c82ef68"><li><code class="notion-inline-code">typeof</code>：这个变量是什么类型。</li></ul><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-b35180bc35cd4a0da7cbca5f27991742" data-id="b35180bc35cd4a0da7cbca5f27991742"><span><div id="b35180bc35cd4a0da7cbca5f27991742" class="notion-header-anchor"></div><a class="notion-hash-link" href="#b35180bc35cd4a0da7cbca5f27991742" title="5.3 keyof typeof"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">5.3 keyof typeof</span></span></h4><div class="notion-text notion-block-cc2818cbb6e94598b6a44770d7e90545">执行顺序：</div><ol start="1" class="notion-list notion-list-numbered notion-block-1630392eb0c34522a16f67ed9b6cde09" style="list-style-type:decimal"><li><code class="notion-inline-code">typeof GoodsType</code> 获取对象类型；</li></ol><ol start="2" class="notion-list notion-list-numbered notion-block-cda1540d591c42958e264fb28597d15e" style="list-style-type:decimal"><li><code class="notion-inline-code">keyof</code> 再获取该类型所有键。</li></ol><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-2124264c668a45119a10db17da4ddf1d" data-id="2124264c668a45119a10db17da4ddf1d"><span><div id="2124264c668a45119a10db17da4ddf1d" class="notion-header-anchor"></div><a class="notion-hash-link" href="#2124264c668a45119a10db17da4ddf1d" title="5.4 as const"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">5.4 as const</span></span></h4><div class="notion-text notion-block-2b091471a49c41598e444c670c567412"><code class="notion-inline-code">as const</code> 会让 TypeScript 使用更精确的字面量类型，而不是把数据宽化成普通的 <code class="notion-inline-code">string[]</code>。</div><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-7fb5e83fcbd34594a44bcff800befb20" data-id="7fb5e83fcbd34594a44bcff800befb20"><span><div id="7fb5e83fcbd34594a44bcff800befb20" class="notion-header-anchor"></div><a class="notion-hash-link" href="#7fb5e83fcbd34594a44bcff800befb20" title="6. any、unknown、void 与 never"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">6. any、unknown、void 与 never</span></span></h3><div class="notion-text notion-block-1accb689d1fe41f189b5339a1e827ae3">本章从「any」「unknown」和「void」等方面说明 any、unknown、void 与 never。</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-2f7bd6c210df4a36a40d266a89ffa0a8" data-id="2f7bd6c210df4a36a40d266a89ffa0a8"><span><div id="2f7bd6c210df4a36a40d266a89ffa0a8" class="notion-header-anchor"></div><a class="notion-hash-link" href="#2f7bd6c210df4a36a40d266a89ffa0a8" title="6.1 any"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">6.1 any</span></span></h4><div class="notion-text notion-block-2cdb4f5d48ac4e7ca96a790992373d9d"><code class="notion-inline-code">any</code> 表示任意类型，会关闭大部分类型检查。</div><div class="notion-text notion-block-7c4cbe32a43c4aab896658e0c0c9f565">上面的代码编译时可能不报错，但运行时可能出现异常。</div><div class="notion-text notion-block-2ef43a60ec4f4db2be4fa959b9812b2d"><code class="notion-inline-code">注意：大量使用 any 会让 TypeScript 逐渐失去意义。</code></div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-536931418c06470aba25bb5f04bdb0bb" data-id="536931418c06470aba25bb5f04bdb0bb"><span><div id="536931418c06470aba25bb5f04bdb0bb" class="notion-header-anchor"></div><a class="notion-hash-link" href="#536931418c06470aba25bb5f04bdb0bb" title="6.2 unknown"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">6.2 unknown</span></span></h4><div class="notion-text notion-block-9488d5a54cbc4ea9be0ea17336a70a42"><code class="notion-inline-code">unknown</code> 同样表示未知类型，但比 <code class="notion-inline-code">any</code> 更安全。</div><div class="notion-text notion-block-278bb476980e4a84a250c06c67f96a3e">在使用 <code class="notion-inline-code">unknown</code> 之前，必须先进行类型判断、类型收窄或断言。</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-23cb74d59ecf4c6da2f7944d0ce9d9b4" data-id="23cb74d59ecf4c6da2f7944d0ce9d9b4"><span><div id="23cb74d59ecf4c6da2f7944d0ce9d9b4" class="notion-header-anchor"></div><a class="notion-hash-link" href="#23cb74d59ecf4c6da2f7944d0ce9d9b4" title="6.3 void"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">6.3 void</span></span></h4><div class="notion-text notion-block-af8c414ba05a4346a538dcc24629c85a"><code class="notion-inline-code">void</code> 通常表示函数没有需要使用的返回值。</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-f48969684bc2458dbef139cf95a4b227" data-id="f48969684bc2458dbef139cf95a4b227"><span><div id="f48969684bc2458dbef139cf95a4b227" class="notion-header-anchor"></div><a class="notion-hash-link" href="#f48969684bc2458dbef139cf95a4b227" title="6.4 never"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">6.4 never</span></span></h4><div class="notion-text notion-block-ec2898b05c5847d79a5d63e8b1b5a0fc"><code class="notion-inline-code">never</code> 表示永远不会正常产生的值。</div><div class="notion-text notion-block-d3df664414cb4578a3d35040513f0361">也可以用于穷尽检查：</div><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-c8d3be42b15d45bea946c6c24fc359c3" data-id="c8d3be42b15d45bea946c6c24fc359c3"><span><div id="c8d3be42b15d45bea946c6c24fc359c3" class="notion-header-anchor"></div><a class="notion-hash-link" href="#c8d3be42b15d45bea946c6c24fc359c3" title="7. 联合类型与交叉类型"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">7. 联合类型与交叉类型</span></span></h3><div class="notion-text notion-block-d0f04f8ea02b43c88208c4c4b4bfd146">本章从「联合类型」和「交叉类型」两方面说明联合类型与交叉类型。</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-55e0c76de27b419fb522f8114cb078cb" data-id="55e0c76de27b419fb522f8114cb078cb"><span><div id="55e0c76de27b419fb522f8114cb078cb" class="notion-header-anchor"></div><a class="notion-hash-link" href="#55e0c76de27b419fb522f8114cb078cb" title="7.1 联合类型"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">7.1 联合类型</span></span></h4><div class="notion-text notion-block-cf849d3c1ef14533ab6ca6bbf0c25a36">联合类型使用 <code class="notion-inline-code">|</code>，表示一个值可以是多种类型中的一种。</div><div class="notion-text notion-block-1c62aab6f46049fb94e1aee54cbb6134">对象联合通常会和可辨识联合一起使用：</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-9253f48520004d3d9b005b07f2e676b9" data-id="9253f48520004d3d9b005b07f2e676b9"><span><div id="9253f48520004d3d9b005b07f2e676b9" class="notion-header-anchor"></div><a class="notion-hash-link" href="#9253f48520004d3d9b005b07f2e676b9" title="7.2 交叉类型"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">7.2 交叉类型</span></span></h4><div class="notion-text notion-block-63817b4a51e643ceb6bd56abcfd9c566">交叉类型使用 <code class="notion-inline-code">&amp;</code>，表示同时拥有多个类型的全部成员。</div><div class="notion-text notion-block-7692d090ff484efd852bea2ce9fab00c">简单理解：</div><ul class="notion-list notion-list-disc notion-block-4cb568cd0e2743a3867d2544e2cedee4"><li>联合类型：或；</li></ul><ul class="notion-list notion-list-disc notion-block-396b75f2e12a43768c173411109faf58"><li>交叉类型：且。</li></ul><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-d0102b0b066547758eb889e33f934bc1" data-id="d0102b0b066547758eb889e33f934bc1"><span><div id="d0102b0b066547758eb889e33f934bc1" class="notion-header-anchor"></div><a class="notion-hash-link" href="#d0102b0b066547758eb889e33f934bc1" title="8. type 与 interface"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">8. type 与 interface</span></span></h3><div class="notion-text notion-block-d3049ec054814f3aa1a3f430c43c9cde"><code class="notion-inline-code">type</code> 和 <code class="notion-inline-code">interface</code> 都可以描述对象结构。</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-9b9e0408726b4c3eae850565ac4c5311" data-id="9b9e0408726b4c3eae850565ac4c5311"><span><div id="9b9e0408726b4c3eae850565ac4c5311" class="notion-header-anchor"></div><a class="notion-hash-link" href="#9b9e0408726b4c3eae850565ac4c5311" title="8.1 共同点"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">8.1 共同点</span></span></h4><ul class="notion-list notion-list-disc notion-block-6a54c8202d0549bebc9e451e567843c2"><li>都可以描述对象结构；</li></ul><ul class="notion-list notion-list-disc notion-block-b6591497f05b44c6ac24dc234d34f029"><li>都可以被类实现；</li></ul><ul class="notion-list notion-list-disc notion-block-658787aa845041d983f2283ebe692a82"><li>都可以扩展已有类型。</li></ul><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-b921dccd6fc74232be3ef3d0ac54e7a4" data-id="b921dccd6fc74232be3ef3d0ac54e7a4"><span><div id="b921dccd6fc74232be3ef3d0ac54e7a4" class="notion-header-anchor"></div><a class="notion-hash-link" href="#b921dccd6fc74232be3ef3d0ac54e7a4" title="8.2 interface 的特点"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">8.2 interface 的特点</span></span></h4><div class="notion-text notion-block-4e531e50914b4514ba2c9b37cde30333"><code class="notion-inline-code">interface</code> 支持声明合并：</div><div class="notion-text notion-block-aba12bebfc5e4fa1be163ba40fc4d0a3">最终会合并为同一个 <code class="notion-inline-code">Window</code> 类型。</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-d0cd08508f0f416a98dc97d44fb43e2e" data-id="d0cd08508f0f416a98dc97d44fb43e2e"><span><div id="d0cd08508f0f416a98dc97d44fb43e2e" class="notion-header-anchor"></div><a class="notion-hash-link" href="#d0cd08508f0f416a98dc97d44fb43e2e" title="8.3 type 的特点"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">8.3 type 的特点</span></span></h4><div class="notion-text notion-block-c81120588183459ea161f1b1255b7028"><code class="notion-inline-code">type</code> 可以描述更多复杂类型：</div><div class="notion-text notion-block-4bea68b834164e4f871cb9fd14e3ecf3">常见选择方法：</div><ul class="notion-list notion-list-disc notion-block-c606e8e67177484d8c3f0381c4b2eb4e"><li>描述对象结构、公共接口时优先使用 <code class="notion-inline-code">interface</code>；</li></ul><ul class="notion-list notion-list-disc notion-block-3bd106cf465b490fa1105e11526914a3"><li>联合类型、交叉类型、元组和复杂类型运算使用 <code class="notion-inline-code">type</code>。</li></ul><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-13c909de4b41421ca5095491d939ea92" data-id="13c909de4b41421ca5095491d939ea92"><span><div id="13c909de4b41421ca5095491d939ea92" class="notion-header-anchor"></div><a class="notion-hash-link" href="#13c909de4b41421ca5095491d939ea92" title="9. 泛型"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">9. 泛型</span></span></h3><div class="notion-text notion-block-470e261df4e6420099526c542856ae96">泛型可以理解为“类型参数”。</div><div class="notion-text notion-block-2d126eca587c4e04bdda2fb4eecf6261">它允许函数、类和接口在定义时不写死具体类型，在使用时再确定类型。</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-2b34e1fcc0da49449b73be47a47890af" data-id="2b34e1fcc0da49449b73be47a47890af"><span><div id="2b34e1fcc0da49449b73be47a47890af" class="notion-header-anchor"></div><a class="notion-hash-link" href="#2b34e1fcc0da49449b73be47a47890af" title="9.1 函数泛型"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">9.1 函数泛型</span></span></h4><div class="notion-text notion-block-f0cb475c5b8241d4864745eaf82a5d71">很多情况下 TypeScript 可以自动推导泛型参数：</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-80dd52dd931c4c2399b5e6d0e34634b6" data-id="80dd52dd931c4c2399b5e6d0e34634b6"><span><div id="80dd52dd931c4c2399b5e6d0e34634b6" class="notion-header-anchor"></div><a class="notion-hash-link" href="#80dd52dd931c4c2399b5e6d0e34634b6" title="9.2 接口泛型"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">9.2 接口泛型</span></span></h4><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-4867f94439ac491aa84027ae4b72582e" data-id="4867f94439ac491aa84027ae4b72582e"><span><div id="4867f94439ac491aa84027ae4b72582e" class="notion-header-anchor"></div><a class="notion-hash-link" href="#4867f94439ac491aa84027ae4b72582e" title="9.3 类泛型"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">9.3 类泛型</span></span></h4><div class="notion-text notion-block-d495a3a938514d4f87faf686d95f36a1">泛型的作用：</div><ul class="notion-list notion-list-disc notion-block-e22fe3faf35c4d9ba301e51993051dcb"><li>提高代码复用性；</li></ul><ul class="notion-list notion-list-disc notion-block-be128d34adf445478b703e8ddb7886ee"><li>保留明确类型；</li></ul><ul class="notion-list notion-list-disc notion-block-cd6f1b94e790402cae7a5e51dc7dcd03"><li>减少 <code class="notion-inline-code">any</code>；</li></ul><ul class="notion-list notion-list-disc notion-block-f83462b4f7084cf5af01dbfcf8e57be9"><li>让通用数据结构和工具函数更加安全。</li></ul><div class="notion-text notion-block-3db63c8605924828a3f4745288a77c6f">在游戏项目中，资源加载、对象池、接口返回结果和列表组件都适合使用泛型。</div><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-45e31b49627741a1bb2f2e14af5540eb" data-id="45e31b49627741a1bb2f2e14af5540eb"><span><div id="45e31b49627741a1bb2f2e14af5540eb" class="notion-header-anchor"></div><a class="notion-hash-link" href="#45e31b49627741a1bb2f2e14af5540eb" title="10. TypeScript 工具类型"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">10. TypeScript 工具类型</span></span></h3><div class="notion-text notion-block-c7b4e2295aa74ebfb980e83cd2dae487">TypeScript 内置了许多常用工具类型。</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-c9383573c7c24fb694c8cbff7eb96ec9" data-id="c9383573c7c24fb694c8cbff7eb96ec9"><span><div id="c9383573c7c24fb694c8cbff7eb96ec9" class="notion-header-anchor"></div><a class="notion-hash-link" href="#c9383573c7c24fb694c8cbff7eb96ec9" title="10.1 Partial"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">10.1 Partial</span></span></h4><div class="notion-text notion-block-6680a91a07b94f32b16801ddcde2e2ab">将所有属性变成可选属性：</div><div class="notion-text notion-block-d614a73e4a0f4dcd87c5ebb61d229dc2">适合局部更新：</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-fa0c724a7314470b9d1593a5ebb0b5b1" data-id="fa0c724a7314470b9d1593a5ebb0b5b1"><span><div id="fa0c724a7314470b9d1593a5ebb0b5b1" class="notion-header-anchor"></div><a class="notion-hash-link" href="#fa0c724a7314470b9d1593a5ebb0b5b1" title="10.2 Required"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">10.2 Required</span></span></h4><div class="notion-text notion-block-f26be7943409400ba0fc4527bea5f918">将所有属性变成必填属性：</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-c22e964864bd4fd39a81386ab7230b45" data-id="c22e964864bd4fd39a81386ab7230b45"><span><div id="c22e964864bd4fd39a81386ab7230b45" class="notion-header-anchor"></div><a class="notion-hash-link" href="#c22e964864bd4fd39a81386ab7230b45" title="10.3 Readonly"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">10.3 Readonly</span></span></h4><div class="notion-text notion-block-1c8aee4d67d04a2ab4a84c30e3047a01">将所有属性变成只读属性：</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-4053826fa35d4e1c8dd66b71a73c1688" data-id="4053826fa35d4e1c8dd66b71a73c1688"><span><div id="4053826fa35d4e1c8dd66b71a73c1688" class="notion-header-anchor"></div><a class="notion-hash-link" href="#4053826fa35d4e1c8dd66b71a73c1688" title="10.4 Pick"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">10.4 Pick</span></span></h4><div class="notion-text notion-block-6626da89988f47ada661f9420166c2f2">选取部分字段：</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-601f629fcbae40bdbe37cbc663e1a03a" data-id="601f629fcbae40bdbe37cbc663e1a03a"><span><div id="601f629fcbae40bdbe37cbc663e1a03a" class="notion-header-anchor"></div><a class="notion-hash-link" href="#601f629fcbae40bdbe37cbc663e1a03a" title="10.5 Omit"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">10.5 Omit</span></span></h4><div class="notion-text notion-block-17612f9517a1430da4125584f4f7223c">排除部分字段：</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-65e8a096d98549f49f2f89152bde2d47" data-id="65e8a096d98549f49f2f89152bde2d47"><span><div id="65e8a096d98549f49f2f89152bde2d47" class="notion-header-anchor"></div><a class="notion-hash-link" href="#65e8a096d98549f49f2f89152bde2d47" title="10.6 Record"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">10.6 Record</span></span></h4><div class="notion-text notion-block-f4151bbeba444a2eb7e750d05ff1b8af">创建键值映射：</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-b0941a330bf14e4b9cd5256c668e0216" data-id="b0941a330bf14e4b9cd5256c668e0216"><span><div id="b0941a330bf14e4b9cd5256c668e0216" class="notion-header-anchor"></div><a class="notion-hash-link" href="#b0941a330bf14e4b9cd5256c668e0216" title="10.7 ReturnType 与 Parameters"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">10.7 ReturnType 与 Parameters</span></span></h4><div class="notion-text notion-block-f74ce19543324eaf8b03880d8bf7ef06">常见使用总结：</div><ul class="notion-list notion-list-disc notion-block-cfeaba4054d547d5ba8258458a04f5ac"><li><code class="notion-inline-code">Partial</code>：局部修改；</li></ul><ul class="notion-list notion-list-disc notion-block-56282622649940219fc220c2ff2de06e"><li><code class="notion-inline-code">Pick</code>：选择字段；</li></ul><ul class="notion-list notion-list-disc notion-block-487a2780285b43b6a35deac4b3041420"><li><code class="notion-inline-code">Omit</code>：排除字段；</li></ul><ul class="notion-list notion-list-disc notion-block-1ca1bafa41af4afda76ecbc883e16578"><li><code class="notion-inline-code">Record</code>：字典映射；</li></ul><ul class="notion-list notion-list-disc notion-block-e7dc450ee15f42cfb92b546a4825e642"><li><code class="notion-inline-code">ReturnType</code>：获取函数返回值类型；</li></ul><ul class="notion-list notion-list-disc notion-block-390d5ff3fc1b46688bd50ef7ca25e9b5"><li><code class="notion-inline-code">Parameters</code>：获取函数参数元组。</li></ul><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-59574817f2ce4bc29eb168cf025dd2eb" data-id="59574817f2ce4bc29eb168cf025dd2eb"><span><div id="59574817f2ce4bc29eb168cf025dd2eb" class="notion-header-anchor"></div><a class="notion-hash-link" href="#59574817f2ce4bc29eb168cf025dd2eb" title="11. 类与访问修饰符"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">11. 类与访问修饰符</span></span></h3><div class="notion-text notion-block-247764d1d5714abaa8a2812d89d528f4">TypeScript 支持 <code class="notion-inline-code">public</code>、<code class="notion-inline-code">protected</code> 和 <code class="notion-inline-code">private</code>。</div><table class="notion-simple-table notion-block-5d7f72682e5747bfa252a693fd1f97bf"><tbody><tr class="notion-simple-table-row notion-simple-table-header-row notion-block-020b2fe6b7a8484e93a68ac5eefc6fc6"><td class="" style="width:120px"><div class="notion-simple-table-cell">修饰符</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">当前类</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">子类</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">类外部</div></td></tr><tr class="notion-simple-table-row notion-block-8910ef78678f447b82035fe634356339"><td class="" style="width:120px"><div class="notion-simple-table-cell"><code class="notion-inline-code">public</code></div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">可以</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">可以</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">可以</div></td></tr><tr class="notion-simple-table-row notion-block-802b15792c6f47dfb81ca5669f1267a0"><td class="" style="width:120px"><div class="notion-simple-table-cell"><code class="notion-inline-code">protected</code></div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">可以</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">可以</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">不可以</div></td></tr><tr class="notion-simple-table-row notion-block-cc9a086b09eb4350b98387442667f001"><td class="" style="width:120px"><div class="notion-simple-table-cell"><code class="notion-inline-code">private</code></div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">可以</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">不可以</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">不可以</div></td></tr></tbody></table><div class="notion-text notion-block-e1b38a8a3a904270a861ef07b4c8a6e1"><code class="notion-inline-code">public</code> 是默认修饰符。</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-87a4c42c21034bed9a35757301a27af1" data-id="87a4c42c21034bed9a35757301a27af1"><span><div id="87a4c42c21034bed9a35757301a27af1" class="notion-header-anchor"></div><a class="notion-hash-link" href="#87a4c42c21034bed9a35757301a27af1" title="11.1 private 与 # 私有字段"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">11.1 <code class="notion-inline-code">private</code> 与 <code class="notion-inline-code">#</code> 私有字段</span></span></h4><div class="notion-text notion-block-e0cb3f16964c418cb6eb462075ae0f31">区别：</div><ul class="notion-list notion-list-disc notion-block-a4d7c97d384a48018aca61bf65a9b8e6"><li><code class="notion-inline-code">private</code> 主要由 TypeScript 在编译阶段检查；</li></ul><ul class="notion-list notion-list-disc notion-block-ad5b783392a548b8b950b3555cf6750a"><li><code class="notion-inline-code">#salary</code> 是 JavaScript 原生私有字段；</li></ul><ul class="notion-list notion-list-disc notion-block-a3e18ba340bf41c484b0ba069b7da848"><li><code class="notion-inline-code">#</code> 私有字段在运行时也不能从类外部直接访问。</li></ul><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-1c31655ecad543259851008ed330c7d3" data-id="1c31655ecad543259851008ed330c7d3"><span><div id="1c31655ecad543259851008ed330c7d3" class="notion-header-anchor"></div><a class="notion-hash-link" href="#1c31655ecad543259851008ed330c7d3" title="12. 抽象类"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">12. 抽象类</span></span></h3><div class="notion-text notion-block-351dc0e89873435f822d6e0c8f9ef046">抽象类使用 <code class="notion-inline-code">abstract class</code> 声明，不能被直接实例化，只能被继承。</div><div class="notion-text notion-block-777ca1d40a594549ad74b1a00b6f69aa">抽象类可以：</div><ul class="notion-list notion-list-disc notion-block-482582b1c8a242baa9001be70d9c144c"><li>提供公共属性；</li></ul><ul class="notion-list notion-list-disc notion-block-b8e45c6b334e464da2c092cde64e1a51"><li>提供已经实现的方法；</li></ul><ul class="notion-list notion-list-disc notion-block-99898bab104044329ecd8c0dbc7da86d"><li>定义必须由子类实现的抽象方法；</li></ul><ul class="notion-list notion-list-disc notion-block-8d6ceda55647436b8abbc031fe941fa6"><li>作为一组子类的公共基类。</li></ul><div class="notion-text notion-block-7a98312d1d38405e965c31dce90dd553">抽象类和接口的主要区别：</div><ul class="notion-list notion-list-disc notion-block-af1ad0da48ea4ee28e104fef638d6826"><li>抽象类会生成运行时代码；</li></ul><ul class="notion-list notion-list-disc notion-block-a93716208be74049a18687492e073712"><li>接口只用于类型检查；</li></ul><ul class="notion-list notion-list-disc notion-block-0deddc58f5b24e2493fe2cfdfec79a89"><li>一个类只能继承一个抽象类；</li></ul><ul class="notion-list notion-list-disc notion-block-9b97c138d76e493daaf93978402eb1be"><li>一个类可以实现多个接口。</li></ul><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-2eeef0e58ef64ac487b785347979075b" data-id="2eeef0e58ef64ac487b785347979075b"><span><div id="2eeef0e58ef64ac487b785347979075b" class="notion-header-anchor"></div><a class="notion-hash-link" href="#2eeef0e58ef64ac487b785347979075b" title="13. 常见符号"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">13. 常见符号</span></span></h3><div class="notion-text notion-block-35d8e8009a5c4f8ca5148a1fdc94bbb1">本章说明可选属性、可选链与空值合并等常见符号的含义和使用边界。</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-887716db7df4455897763f6e48efe9f4" data-id="887716db7df4455897763f6e48efe9f4"><span><div id="887716db7df4455897763f6e48efe9f4" class="notion-header-anchor"></div><a class="notion-hash-link" href="#887716db7df4455897763f6e48efe9f4" title="13.1 ? 可选"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">13.1 ? 可选</span></span></h4><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-de3c755d12294d25ab4efe27a2055ce5" data-id="de3c755d12294d25ab4efe27a2055ce5"><span><div id="de3c755d12294d25ab4efe27a2055ce5" class="notion-header-anchor"></div><a class="notion-hash-link" href="#de3c755d12294d25ab4efe27a2055ce5" title="13.2 ?. 可选链"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">13.2 ?. 可选链</span></span></h4><div class="notion-text notion-block-75201926e05c4513996248c43e25484e">左侧为 <code class="notion-inline-code">null</code> 或 <code class="notion-inline-code">undefined</code> 时，不再继续访问，结果为 <code class="notion-inline-code">undefined</code>。</div><div class="notion-text notion-block-667d439a28cc4e27843c381d92ab6a85">Cocos 中常见写法：</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-8a46e65488a3433c938497c0b46f54e5" data-id="8a46e65488a3433c938497c0b46f54e5"><span><div id="8a46e65488a3433c938497c0b46f54e5" class="notion-header-anchor"></div><a class="notion-hash-link" href="#8a46e65488a3433c938497c0b46f54e5" title="13.3 ?? 空值合并"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">13.3 <code class="notion-inline-code">??</code> 空值合并</span></span></h4><div class="notion-text notion-block-0d795f8cc4944844a9f7a43840ba67e4">只有左侧是 <code class="notion-inline-code">null</code> 或 <code class="notion-inline-code">undefined</code> 时才使用右侧默认值。</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-42ed95bcf2644822b6f3db711053b8af" data-id="42ed95bcf2644822b6f3db711053b8af"><span><div id="42ed95bcf2644822b6f3db711053b8af" class="notion-header-anchor"></div><a class="notion-hash-link" href="#42ed95bcf2644822b6f3db711053b8af" title="13.4 ! 非空断言"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">13.4 ! 非空断言</span></span></h4><div class="notion-text notion-block-2d395ffc67294cfbb6e5cb7bbe65ac9d">表示开发者确定结果不为空。</div><div class="notion-text notion-block-7d9c74aa2be0405dbe04efe557bb1b90"><code class="notion-inline-code">注意：非空断言只关闭编译检查，不会自动保证运行时一定有值。</code></div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-d32ff8a028244e59a9c74596d7e21c2a" data-id="d32ff8a028244e59a9c74596d7e21c2a"><span><div id="d32ff8a028244e59a9c74596d7e21c2a" class="notion-header-anchor"></div><a class="notion-hash-link" href="#d32ff8a028244e59a9c74596d7e21c2a" title="13.5 ! 属性确定赋值断言"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">13.5 ! 属性确定赋值断言</span></span></h4><div class="notion-text notion-block-d41de4f5d254428595d963b29c7c721b">表示该属性会在其他位置完成初始化。</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-af98347c64e24993bf985414699b8856" data-id="af98347c64e24993bf985414699b8856"><span><div id="af98347c64e24993bf985414699b8856" class="notion-header-anchor"></div><a class="notion-hash-link" href="#af98347c64e24993bf985414699b8856" title="13.6 _ 下划线"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">13.6 _ 下划线</span></span></h4><div class="notion-text notion-block-da6bd9c8e0464f50a4730e9b18326aed">数字分隔符：</div><div class="notion-text notion-block-ff22ab80479b45c2b4243997754ad0e1">表示暂时不使用的参数：</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-b79e6ab82c97441dbdefb735a5c52e02" data-id="b79e6ab82c97441dbdefb735a5c52e02"><span><div id="b79e6ab82c97441dbdefb735a5c52e02" class="notion-header-anchor"></div><a class="notion-hash-link" href="#b79e6ab82c97441dbdefb735a5c52e02" title="13.7 &amp; 与 |"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">13.7 <code class="notion-inline-code">&amp;</code> 与 <code class="notion-inline-code">|</code></span></span></h4><ul class="notion-list notion-list-disc notion-block-262ac46d3ada4582a6e4bdf4524ba1b8"><li><code class="notion-inline-code">&amp;</code>：交叉类型；</li></ul><ul class="notion-list notion-list-disc notion-block-a64f1200e21640f98ab00f1a469d2d79"><li><code class="notion-inline-code">|</code>：联合类型。</li></ul><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-d0471d01811347af8c6afabeb53c8a0b" data-id="d0471d01811347af8c6afabeb53c8a0b"><span><div id="d0471d01811347af8c6afabeb53c8a0b" class="notion-header-anchor"></div><a class="notion-hash-link" href="#d0471d01811347af8c6afabeb53c8a0b" title="13.8 #"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">13.8 #</span></span></h4><div class="notion-text notion-block-70c2b54ae4ac47d5afcddc75978b8ccd">JavaScript 原生私有字段：</div><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-ce973a49eafa4fddb5929877b8e1a7f9" data-id="ce973a49eafa4fddb5929877b8e1a7f9"><span><div id="ce973a49eafa4fddb5929877b8e1a7f9" class="notion-header-anchor"></div><a class="notion-hash-link" href="#ce973a49eafa4fddb5929877b8e1a7f9" title="14. 模块导入与路径解析"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">14. 模块导入与路径解析</span></span></h3><div class="notion-text notion-block-6e2fafe9c7c24df0bd49d588a3f54e82">示例：</div><div class="notion-text notion-block-06ee1f82681a4f18b0a1f573dc42ce93">假设当前文件是：</div><div class="notion-text notion-block-dca42176c891449e8c082041a98dc8e0">解析过程：</div><div class="notion-text notion-block-096f002c043d498796ff79ab2cde2c1e">具体匹配到 <code class="notion-inline-code">.ts</code>、<code class="notion-inline-code">.tsx</code>、<code class="notion-inline-code">.d.ts</code>、<code class="notion-inline-code">.js</code>、<code class="notion-inline-code">package.json</code> 导出项还是其他文件，取决于：</div><ul class="notion-list notion-list-disc notion-block-0f7534c079d84bb2ba2a30f52457c8ee"><li><code class="notion-inline-code">moduleResolution</code> 配置；</li></ul><ul class="notion-list notion-list-disc notion-block-76a66733b467405c938fc4862a86cf0e"><li>使用的运行时；</li></ul><ul class="notion-list notion-list-disc notion-block-ccb6ae24f3dd497984e90746e4305878"><li>打包器；</li></ul><ul class="notion-list notion-list-disc notion-block-98daa7c0e7db47509c464e27f35aef72"><li><code class="notion-inline-code">package.json</code> 的 <code class="notion-inline-code">exports</code> 和 <code class="notion-inline-code">imports</code>；</li></ul><ul class="notion-list notion-list-disc notion-block-1fc54fea3f8541daa3d34554ddd7fe18"><li>TypeScript 版本和其他编译选项。</li></ul><div class="notion-text notion-block-299fe4ba9c0e4c7fbdb871edda760f43">因此，“不以 <code class="notion-inline-code">./</code> 或 <code class="notion-inline-code">../</code> 开头就一定从 <code class="notion-inline-code">node_modules</code> 查找”过于简化。它属于<b>裸模块说明符（bare specifier）</b>，如何解析取决于当前模块解析模式。</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-3b9fc7c1b79d4d5aa1541392f40e042d" data-id="3b9fc7c1b79d4d5aa1541392f40e042d"><span><div id="3b9fc7c1b79d4d5aa1541392f40e042d" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3b9fc7c1b79d4d5aa1541392f40e042d" title="14.1 常见路径形式"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">14.1 常见路径形式</span></span></h4><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-ec017a20e7f94a40be8e955bc4caeaf9" data-id="ec017a20e7f94a40be8e955bc4caeaf9"><span><div id="ec017a20e7f94a40be8e955bc4caeaf9" class="notion-header-anchor"></div><a class="notion-hash-link" href="#ec017a20e7f94a40be8e955bc4caeaf9" title="14.2 路径别名"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">14.2 路径别名</span></span></h4><div class="notion-text notion-block-aae6f092629a4ec89628cefa5b827c5f"><code class="notion-inline-code">@/</code> 并不是 JavaScript 或 TypeScript 内置语法，需要在 <code class="notion-inline-code">tsconfig.json</code> 中配置，并确保运行时或打包器也理解相同映射。</div><div class="notion-text notion-block-eeda52da62914e8eaa5742f5a0fc384a">只配置 TypeScript 可能只让编辑器和类型检查通过；实际运行时仍需由 Vite、Webpack、Node.js 或对应框架配置解析。</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-336ddc7024764c56b5dd76da467ced24" data-id="336ddc7024764c56b5dd76da467ced24"><span><div id="336ddc7024764c56b5dd76da467ced24" class="notion-header-anchor"></div><a class="notion-hash-link" href="#336ddc7024764c56b5dd76da467ced24" title="14.3 是否写扩展名"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">14.3 是否写扩展名</span></span></h4><div class="notion-text notion-block-1444fcbd78864eb2989f2741fb9ed924">在很多 TypeScript 项目中，相对导入会省略扩展名：</div><div class="notion-text notion-block-9066b4e7ed144b459851753a19dc0794">是否允许直接写 <code class="notion-inline-code">.ts</code>，取决于编译配置和运行方式。不要把“TypeScript 总是不允许扩展名”或“总是允许扩展名”当成固定规则。</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-357d1238081742a7b2493d6a368bf909" data-id="357d1238081742a7b2493d6a368bf909"><span><div id="357d1238081742a7b2493d6a368bf909" class="notion-header-anchor"></div><a class="notion-hash-link" href="#357d1238081742a7b2493d6a368bf909" title="14.4 导入方式"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">14.4 导入方式</span></span></h4><div class="notion-text notion-block-53e432bf9185465a809dc469a22378e7"><code class="notion-inline-code">import type</code> 会明确表示只在类型检查阶段使用，避免无意生成运行时导入。</div><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-96a0979758db4dd9ac1736a771ef4f54" data-id="96a0979758db4dd9ac1736a771ef4f54"><span><div id="96a0979758db4dd9ac1736a771ef4f54" class="notion-header-anchor"></div><a class="notion-hash-link" href="#96a0979758db4dd9ac1736a771ef4f54" title="15. 扩展全局属性与第三方模块声明"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">15. 扩展全局属性与第三方模块声明</span></span></h3><div class="notion-text notion-block-8e0e24c075f94edfb10c28455585a3cb">本章从「扩展 window」和「声明第三方模块」两方面说明扩展全局属性与第三方模块声明。</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-7e931c15fa934eee9af3a093fce298cf" data-id="7e931c15fa934eee9af3a093fce298cf"><span><div id="7e931c15fa934eee9af3a093fce298cf" class="notion-header-anchor"></div><a class="notion-hash-link" href="#7e931c15fa934eee9af3a093fce298cf" title="15.1 扩展 window"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">15.1 扩展 window</span></span></h4><div class="notion-text notion-block-a40dbe835ab5479a91ba7d67234d7467">可以创建 <code class="notion-inline-code">global.d.ts</code>：</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-1f49be35268247e08ce7508dbcb83ddb" data-id="1f49be35268247e08ce7508dbcb83ddb"><span><div id="1f49be35268247e08ce7508dbcb83ddb" class="notion-header-anchor"></div><a class="notion-hash-link" href="#1f49be35268247e08ce7508dbcb83ddb" title="15.2 声明第三方模块"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">15.2 声明第三方模块</span></span></h4><div class="notion-text notion-block-48a5e6aaff9d4527a73e28898eaad567">第三方库没有类型声明时，可以自己补充：</div><div class="notion-text notion-block-e3ef2880a91b436396f4fa2a7af38157">全局变量：</div><div class="notion-text notion-block-f0041f022bf246149b2a476dc0cf5524"><code class="notion-inline-code">.d.ts</code> 文件只负责提供类型声明，不会自动实现真实功能。</div><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-db6dd6593a6243019d2174e328207a5b" data-id="db6dd6593a6243019d2174e328207a5b"><span><div id="db6dd6593a6243019d2174e328207a5b" class="notion-header-anchor"></div><a class="notion-hash-link" href="#db6dd6593a6243019d2174e328207a5b" title="16. Cocos Creator 中的 TypeScript 实践"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">16. Cocos Creator 中的 TypeScript 实践</span></span></h3><div class="notion-text notion-block-99dd4362c37d4b3cb3e3ed5b1d7f39fe">在 Cocos Creator 项目中，TypeScript 常用于：</div><ul class="notion-list notion-list-disc notion-block-526f93be0c85467bafee92e0b944e1ca"><li>UI 组件；</li></ul><ul class="notion-list notion-list-disc notion-block-02d1489085db4ea58486b81ab89eec5c"><li>节点和组件绑定；</li></ul><ul class="notion-list notion-list-disc notion-block-bceffdc427d34498a289a52d7456cd0b"><li>游戏状态管理；</li></ul><ul class="notion-list notion-list-disc notion-block-abe1866c702648c581ba801527090fde"><li>资源加载；</li></ul><ul class="notion-list notion-list-disc notion-block-bfd798daf468442e92d5892ed2b60317"><li>对象池；</li></ul><ul class="notion-list notion-list-disc notion-block-1516e803f7a14a9289cad31fc1cad4b9"><li>订单和商品数据；</li></ul><ul class="notion-list notion-list-disc notion-block-bf71be7cba614da7ba8eff2ebd43de18"><li>关卡配置；</li></ul><ul class="notion-list notion-list-disc notion-block-bae62ceae92747418b7dd56676ed566c"><li>异步流程。</li></ul><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-6afa6e2596774e268ba1756a61bcc4e3" data-id="6afa6e2596774e268ba1756a61bcc4e3"><span><div id="6afa6e2596774e268ba1756a61bcc4e3" class="notion-header-anchor"></div><a class="notion-hash-link" href="#6afa6e2596774e268ba1756a61bcc4e3" title="16.1 编辑器属性绑定"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">16.1 编辑器属性绑定</span></span></h4><div class="notion-text notion-block-ad695c322b0b4694bd04a80dd8eba008">明确的组件类型可以让 IDE 提供正确提示，也能减少把 <code class="notion-inline-code">Node</code>、<code class="notion-inline-code">Button</code> 和 <code class="notion-inline-code">Label</code> 混用的问题。</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-b2c939828e4a45e79b95b02a3b0f0231" data-id="b2c939828e4a45e79b95b02a3b0f0231"><span><div id="b2c939828e4a45e79b95b02a3b0f0231" class="notion-header-anchor"></div><a class="notion-hash-link" href="#b2c939828e4a45e79b95b02a3b0f0231" title="16.2 数据结构"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">16.2 数据结构</span></span></h4><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-eebf541735f342a1b5a6c718d890df8d" data-id="eebf541735f342a1b5a6c718d890df8d"><span><div id="eebf541735f342a1b5a6c718d890df8d" class="notion-header-anchor"></div><a class="notion-hash-link" href="#eebf541735f342a1b5a6c718d890df8d" title="16.3 异步资源加载"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">16.3 异步资源加载</span></span></h4><div class="notion-text notion-block-e13c1f24f2064804a0bd665b06be5aae">多个资源并行加载：</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-8e83394405104aab8c127e37ce8a3bc9" data-id="8e83394405104aab8c127e37ce8a3bc9"><span><div id="8e83394405104aab8c127e37ce8a3bc9" class="notion-header-anchor"></div><a class="notion-hash-link" href="#8e83394405104aab8c127e37ce8a3bc9" title="16.4 实际使用中的问题"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">16.4 实际使用中的问题</span></span></h4><div class="notion-text notion-block-5d6d3b2b41a148f48093449d2dbf2f6d">项目赶进度时容易出现：</div><div class="notion-text notion-block-569c26598dd0429696a69ee0cffcf146">这种写法虽然方便，但会绕过类型检查。</div><div class="notion-text notion-block-50c26a784e724c63b5c9b6c7d34e0e26">更好的方式是：</div><ul class="notion-list notion-list-disc notion-block-a3cb5a6e811146478524a558eb371c3b"><li>给组件声明明确类型；</li></ul><ul class="notion-list notion-list-disc notion-block-f6a89dd9e74a4f5e8e4515556b31a060"><li>使用接口描述数据结构；</li></ul><ul class="notion-list notion-list-disc notion-block-27fa0c52d8ef40fbb3cf305b312e5a36"><li>使用泛型封装资源加载；</li></ul><ul class="notion-list notion-list-disc notion-block-587d87576537459baca72dc0148ac8c0"><li>对外部数据先使用 <code class="notion-inline-code">unknown</code>，再进行类型判断；</li></ul><ul class="notion-list notion-list-disc notion-block-98937855ca3d4172aebfadcb392cbb17"><li>尽量减少强制断言和 <code class="notion-inline-code">any</code>。</li></ul><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-c5539de0c331461d8dd1c6d87e60d347" data-id="c5539de0c331461d8dd1c6d87e60d347"><span><div id="c5539de0c331461d8dd1c6d87e60d347" class="notion-header-anchor"></div><a class="notion-hash-link" href="#c5539de0c331461d8dd1c6d87e60d347" title="17. 常见易错点"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">17. 常见易错点</span></span></h3><ul class="notion-list notion-list-disc notion-block-9d9f9ee5b4ee47d4a8ef5b625b3b3b31"><li><code class="notion-inline-code">unknown</code> 不能直接使用，必须先进行类型收窄；</li></ul><ul class="notion-list notion-list-disc notion-block-78e5074d72134aa09d7cefd477af484b"><li><code class="notion-inline-code">any</code> 会关闭大部分类型检查；</li></ul><ul class="notion-list notion-list-disc notion-block-d6ac9f5bd122492bbcb10454612a9fdd"><li><code class="notion-inline-code">void</code> 和 <code class="notion-inline-code">never</code> 含义不同；</li></ul><ul class="notion-list notion-list-disc notion-block-355ed28c5e314fd78fc34ed4de8cc017"><li>数组可以使用联合元素类型，不是只能存一种类型；</li></ul><ul class="notion-list notion-list-disc notion-block-35d1f83e396d4cf3ace8fcd332e24dc0"><li>元组强调固定长度和固定位置类型；</li></ul><ul class="notion-list notion-list-disc notion-block-b85727b0d78f4e1ab9590c69c770c3d0"><li><code class="notion-inline-code">keyof</code> 获取类型的键，<code class="notion-inline-code">typeof</code> 获取变量的类型；</li></ul><ul class="notion-list notion-list-disc notion-block-c44195bc4b404b3bacc42cb129e964bc"><li><code class="notion-inline-code">enum</code> 通常会产生运行时代码；</li></ul><ul class="notion-list notion-list-disc notion-block-d2211b246e4f49d996f7f0022173b56b"><li><code class="notion-inline-code">interface</code> 支持声明合并；</li></ul><ul class="notion-list notion-list-disc notion-block-3b0fc85b093140deb9da6e7fdbf49c1f"><li><code class="notion-inline-code">type</code> 更适合联合、交叉、元组和复杂类型运算；</li></ul><ul class="notion-list notion-list-disc notion-block-3db52f4054e04116a8aecb7d5ed1e7e6"><li><code class="notion-inline-code">private</code> 主要是 TypeScript 编译期限制；</li></ul><ul class="notion-list notion-list-disc notion-block-150c481ca95b4d19af59f5a1fcf7a375"><li><code class="notion-inline-code">#</code> 是 JavaScript 原生运行时私有字段；</li></ul><ul class="notion-list notion-list-disc notion-block-60c6eda5707749009594996d5052c974"><li><code class="notion-inline-code">?.</code> 只处理 <code class="notion-inline-code">null</code> 和 <code class="notion-inline-code">undefined</code>；</li></ul><ul class="notion-list notion-list-disc notion-block-375ac23dc4a04a51b91ed522a27ee339"><li><code class="notion-inline-code">??</code> 不会把 <code class="notion-inline-code">0</code>、空字符串和 <code class="notion-inline-code">false</code> 当成空值；</li></ul><ul class="notion-list notion-list-disc notion-block-ef0b91bba9244005934fe02130a0c52b"><li>非空断言 <code class="notion-inline-code">!</code> 不能消除真实的运行时空引用；</li></ul><ul class="notion-list notion-list-disc notion-block-b26467b2f11142ecac8c3f5d2901abf0"><li><code class="notion-inline-code">.d.ts</code> 只描述类型，不会实现第三方 SDK。</li></ul><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-86d02d1d0ef445138dc83acd4a921bbb" data-id="86d02d1d0ef445138dc83acd4a921bbb"><span><div id="86d02d1d0ef445138dc83acd4a921bbb" class="notion-header-anchor"></div><a class="notion-hash-link" href="#86d02d1d0ef445138dc83acd4a921bbb" title="18. 总结"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">18. 总结</span></span></h3><div class="notion-text notion-block-d1ce8f95ca3d49a2a73b5dcf00160d5f">TypeScript 的价值在于把许多接口约束提前到编译阶段。实际项目中应从清晰的数据模型和函数边界开始，再使用泛型、联合类型、类型守卫和工具类型表达复用关系。</div><div class="notion-text notion-block-3e57e56428bc459a9d7004b38492d1c2">类型声明不能替代运行时校验；外部输入、网络数据和跨版本资源仍需要在运行时检查。</div><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-43303d5be9554a3f9220550b8b2dc11d" data-id="43303d5be9554a3f9220550b8b2dc11d"><span><div id="43303d5be9554a3f9220550b8b2dc11d" class="notion-header-anchor"></div><a class="notion-hash-link" href="#43303d5be9554a3f9220550b8b2dc11d" title="19. 参考资料"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">19. 参考资料</span></span></h3><ul class="notion-list notion-list-disc notion-block-748b48d4cf9443858a2cba7028e8cd67"><li><a class="notion-link" href="https://www.typescriptlang.org/docs/handbook/2/everyday-types.html" target="_blank" rel="noopener noreferrer">TypeScript Handbook：Everyday Types</a></li></ul><ul class="notion-list notion-list-disc notion-block-4dcfd54ca8c54479b182758182167cb9"><li><a class="notion-link" href="https://www.typescriptlang.org/docs/handbook/2/keyof-types.html" target="_blank" rel="noopener noreferrer">TypeScript Handbook：Keyof Type Operator</a></li></ul><ul class="notion-list notion-list-disc notion-block-53e84aa1bf904621b2d0cd6236b56da7"><li><a class="notion-link" href="https://www.typescriptlang.org/docs/handbook/2/typeof-types.html" target="_blank" rel="noopener noreferrer">TypeScript Handbook：Typeof Type Operator</a></li></ul><ul class="notion-list notion-list-disc notion-block-e8e52cffffe547269a15ac50155771b0"><li><a class="notion-link" href="https://www.typescriptlang.org/docs/handbook/2/classes.html" target="_blank" rel="noopener noreferrer">TypeScript Handbook：Classes</a></li></ul><ul class="notion-list notion-list-disc notion-block-c93121d224434578bd7fdb59ccc0eaa6"><li><a class="notion-link" href="https://www.typescriptlang.org/docs/handbook/2/generics.html" target="_blank" rel="noopener noreferrer">TypeScript Handbook：Generics</a></li></ul><ul class="notion-list notion-list-disc notion-block-7c6e1b000f5341d88f93004d7f1b62d9"><li><a class="notion-link" href="https://www.typescriptlang.org/docs/handbook/utility-types.html" target="_blank" rel="noopener noreferrer">TypeScript Handbook：Utility Types</a></li></ul><ul class="notion-list notion-list-disc notion-block-6f5391067ef04dc5b7116c16efbd3e73"><li><a class="notion-link" href="https://www.typescriptlang.org/docs/handbook/declaration-merging.html" target="_blank" rel="noopener noreferrer">TypeScript Handbook：Declaration Merging</a></li></ul><ul class="notion-list notion-list-disc notion-block-8062e5b563ff491da5e2a53cc6b2ce49"><li><a class="notion-link" href="https://www.typescriptlang.org/docs/handbook/modules/reference.html" target="_blank" rel="noopener noreferrer">TypeScript Handbook：Modules Reference</a></li></ul></main></div>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[JavaScript 学习笔记]]></title>
            <link>https://www.yyshow.xyz/article/javascript-core-notes</link>
            <guid>https://www.yyshow.xyz/article/javascript-core-notes</guid>
            <pubDate>Fri, 10 Jul 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[整理 JavaScript 数据类型、for...in 与 for...of，以及 splice、slice、toSpliced 的区别和常见误区。]]></description>
            <content:encoded><![CDATA[<div id="notion-article" class="mx-auto overflow-hidden "><main class="notion light-mode notion-page notion-block-399560c488bc81a4888fe53aa97500a9"><div class="notion-viewport"></div><div class="notion-collection-page-properties"></div><div class="notion-text notion-block-580e2e670e4741358b7200a330d4bd0b">本文集中整理 JavaScript 中容易混淆的三组基础知识：数据类型、<code class="notion-inline-code">for...in</code> 与 <code class="notion-inline-code">for...of</code>，以及 <code class="notion-inline-code">splice</code>、<code class="notion-inline-code">slice</code> 与 <code class="notion-inline-code">toSpliced</code>。读完后可以根据遍历目标和是否修改原数组选择合适的写法。</div><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-a7acb270fb934ef49f76038dd2d5c26e" data-id="a7acb270fb934ef49f76038dd2d5c26e"><span><div id="a7acb270fb934ef49f76038dd2d5c26e" class="notion-header-anchor"></div><a class="notion-hash-link" href="#a7acb270fb934ef49f76038dd2d5c26e" title="1. JavaScript 数据类型"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">1. JavaScript 数据类型</span></span></h3><div class="notion-text notion-block-83c0e523d4b241d89796b70c976f3859">JavaScript 的值可以分为<b>原始值（primitive）</b>和<b>对象（object）</b>。</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-627ff80d584347c88e47b8af621b16b5" data-id="627ff80d584347c88e47b8af621b16b5"><span><div id="627ff80d584347c88e47b8af621b16b5" class="notion-header-anchor"></div><a class="notion-hash-link" href="#627ff80d584347c88e47b8af621b16b5" title="1.1 七种原始类型"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">1.1 七种原始类型</span></span></h4><ul class="notion-list notion-list-disc notion-block-d0f1703c51834dd08a4081dc760061e5"><li><code class="notion-inline-code">undefined</code></li></ul><ul class="notion-list notion-list-disc notion-block-f140636dadeb4828904913de42cd2604"><li><code class="notion-inline-code">null</code></li></ul><ul class="notion-list notion-list-disc notion-block-865f5e570124433193f3811c8d0ad0a4"><li><code class="notion-inline-code">boolean</code></li></ul><ul class="notion-list notion-list-disc notion-block-91ed38d1b6964d63ab0ef21f75eb2e70"><li><code class="notion-inline-code">number</code></li></ul><ul class="notion-list notion-list-disc notion-block-8ef770d1951246b8997fd87ecd2abb58"><li><code class="notion-inline-code">bigint</code></li></ul><ul class="notion-list notion-list-disc notion-block-9dc62a0c875e4a72924b54f7795aaafb"><li><code class="notion-inline-code">string</code></li></ul><ul class="notion-list notion-list-disc notion-block-1293187c45794e798af87fe274b5e2f7"><li><code class="notion-inline-code">symbol</code></li></ul><div class="notion-text notion-block-4bdffc1e90af4e4e889ec8694c5fa000">原始值不可变。所谓不可变，是指不能直接改变这个值本身；变量仍然可以重新赋值。</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-18213c8c3b7e4381a047a109c53c54e7" data-id="18213c8c3b7e4381a047a109c53c54e7"><span><div id="18213c8c3b7e4381a047a109c53c54e7" class="notion-header-anchor"></div><a class="notion-hash-link" href="#18213c8c3b7e4381a047a109c53c54e7" title="1.2 对象类型"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">1.2 对象类型</span></span></h4><div class="notion-text notion-block-66e5fb4a1e9f44b59397b492dedca574">除原始值外，其余值都属于对象，包括：</div><ul class="notion-list notion-list-disc notion-block-0983773cafbf44b9a4b07101bbd18c8d"><li>普通对象 <code class="notion-inline-code">Object</code></li></ul><ul class="notion-list notion-list-disc notion-block-948c4020852c4543ad66fbd0de827fbb"><li>数组 <code class="notion-inline-code">Array</code></li></ul><ul class="notion-list notion-list-disc notion-block-b4dd680c746c42f38e27014b605ba443"><li>函数 <code class="notion-inline-code">Function</code></li></ul><ul class="notion-list notion-list-disc notion-block-b7c24fe157ec4f94ba3c18603725af5a"><li>日期 <code class="notion-inline-code">Date</code></li></ul><ul class="notion-list notion-list-disc notion-block-84802a21bcea498ebe664383950f5f37"><li>正则表达式 <code class="notion-inline-code">RegExp</code></li></ul><ul class="notion-list notion-list-disc notion-block-1baa1b7eaa5f4bc188047899cddfaf92"><li><code class="notion-inline-code">Map</code>、<code class="notion-inline-code">Set</code></li></ul><ul class="notion-list notion-list-disc notion-block-6da342a26d524f6baaa3307238465c62"><li><code class="notion-inline-code">Promise</code></li></ul><div class="notion-text notion-block-d296b26aecdd49aeb804f2802dc2b498">数组和函数在类型体系上也是对象，但函数还具有可调用能力。</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-79a62da9574346ab80aff80f34f77428" data-id="79a62da9574346ab80aff80f34f77428"><span><div id="79a62da9574346ab80aff80f34f77428" class="notion-header-anchor"></div><a class="notion-hash-link" href="#79a62da9574346ab80aff80f34f77428" title="1.3 typeof 常见结果"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">1.3 <code class="notion-inline-code">typeof</code> 常见结果</span></span></h4><div class="notion-text notion-block-8c4af69d1efc4323a3b6a2a35380aa84">判断数组应使用：</div><div class="notion-text notion-block-161634ab99c443ca818400814dc0aab2">判断 <code class="notion-inline-code">null</code> 应直接比较：</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-69ce0b2662db4371b2163a9e434456f4" data-id="69ce0b2662db4371b2163a9e434456f4"><span><div id="69ce0b2662db4371b2163a9e434456f4" class="notion-header-anchor"></div><a class="notion-hash-link" href="#69ce0b2662db4371b2163a9e434456f4" title="1.4 number 的注意事项"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">1.4 <code class="notion-inline-code">number</code> 的注意事项</span></span></h4><div class="notion-text notion-block-51786c080d954e3082935fba5eedf435">JavaScript 的普通数字采用 IEEE 754 双精度浮点格式，因此：</div><div class="notion-text notion-block-0aaa20b88b73402eb2affd50f471b649">需要精确处理货币时，常见做法是使用整数最小单位，例如把 10.25 元保存为 1025 分；超出安全整数范围时可考虑 <code class="notion-inline-code">bigint</code>。</div><div class="notion-text notion-block-a0cc50cf227549349cd8b4d5b7485d15"><code class="notion-inline-code">number</code> 与 <code class="notion-inline-code">bigint</code> 不能直接混合运算：</div><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-cbffd65591a54336a74682fe20539942" data-id="cbffd65591a54336a74682fe20539942"><span><div id="cbffd65591a54336a74682fe20539942" class="notion-header-anchor"></div><a class="notion-hash-link" href="#cbffd65591a54336a74682fe20539942" title="2. for...in 与 for...of"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">2. <code class="notion-inline-code">for...in</code> 与 <code class="notion-inline-code">for...of</code></span></span></h3><div class="notion-text notion-block-64098739a69241a4aa81a97aeeb36c6a">本章比较对象键遍历、可迭代值遍历和数组遍历三类场景。</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-70b4be563da54cc0b94b6787dc854a1b" data-id="70b4be563da54cc0b94b6787dc854a1b"><span><div id="70b4be563da54cc0b94b6787dc854a1b" class="notion-header-anchor"></div><a class="notion-hash-link" href="#70b4be563da54cc0b94b6787dc854a1b" title="2.1 for...in"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">2.1 <code class="notion-inline-code">for...in</code></span></span></h4><div class="notion-text notion-block-ce6c82cc490a4c42ac29de5ccd9daf01"><code class="notion-inline-code">for...in</code> 遍历对象的<b>可枚举字符串属性键</b>，也可能包含原型链上的属性。</div><div class="notion-text notion-block-92ddb05e94664001a1dac26760abd3c0">现代代码优先使用 <code class="notion-inline-code">Object.hasOwn(obj, key)</code>，而不是直接调用 <code class="notion-inline-code">obj.hasOwnProperty(key)</code>，因为对象可能没有继承该方法，或存在同名属性。</div><div class="notion-text notion-block-d72e1baeb1644f909567ab150c867d08">适合场景：</div><ul class="notion-list notion-list-disc notion-block-7c53e2f8f7d14b2f82f2c732bd437b50"><li>枚举普通对象的键；</li></ul><ul class="notion-list notion-list-disc notion-block-411def1f0a0b4bb6880f5f08e2c61ad6"><li>需要处理属性名；</li></ul><ul class="notion-list notion-list-disc notion-block-d1773764d0234879ae58fd54178a740b"><li>明确理解原型链和可枚举性。</li></ul><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-5520fe82189a41548e4045dcfa933a29" data-id="5520fe82189a41548e4045dcfa933a29"><span><div id="5520fe82189a41548e4045dcfa933a29" class="notion-header-anchor"></div><a class="notion-hash-link" href="#5520fe82189a41548e4045dcfa933a29" title="2.2 for...of"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">2.2 <code class="notion-inline-code">for...of</code></span></span></h4><div class="notion-text notion-block-9b0ab1ae183b458d82a165fdf3d78029"><code class="notion-inline-code">for...of</code> 遍历<b>可迭代对象产生的值</b>。</div><div class="notion-text notion-block-84f4a66f0cdd4da2957b7b2fae323407">常见可迭代对象：</div><ul class="notion-list notion-list-disc notion-block-652bf88a430d4eaea02f01ae6f2daea6"><li><code class="notion-inline-code">Array</code></li></ul><ul class="notion-list notion-list-disc notion-block-fa52845496a6444fb4990d6432a836d8"><li><code class="notion-inline-code">String</code></li></ul><ul class="notion-list notion-list-disc notion-block-1a968390cc8f4d9aad1e2fd6cd24e585"><li><code class="notion-inline-code">Map</code></li></ul><ul class="notion-list notion-list-disc notion-block-93f99426382b423cbc33bad9e4434501"><li><code class="notion-inline-code">Set</code></li></ul><ul class="notion-list notion-list-disc notion-block-c2457ca6b87d4965aad5d43b8ac9e664"><li><code class="notion-inline-code">TypedArray</code></li></ul><ul class="notion-list notion-list-disc notion-block-84846f309621428fb93cd2e25b1378e2"><li><code class="notion-inline-code">NodeList</code></li></ul><ul class="notion-list notion-list-disc notion-block-046771f6d899436191f73ff47c10db8e"><li>自定义实现 <code class="notion-inline-code">[Symbol.iterator]</code> 的对象</li></ul><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-3279fe2e65cb42ee8e8c0ff22c871524" data-id="3279fe2e65cb42ee8e8c0ff22c871524"><span><div id="3279fe2e65cb42ee8e8c0ff22c871524" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3279fe2e65cb42ee8e8c0ff22c871524" title="2.3 为什么不推荐用 for...in 遍历数组"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">2.3 为什么不推荐用 <code class="notion-inline-code">for...in</code> 遍历数组</span></span></h4><div class="notion-text notion-block-e13a3cfb62d247129ea43464898ca662">可能输出：</div><div class="notion-text notion-block-3ab777ac97d3437ea0c16e19cff8c0d3">而且数组索引以字符串键出现，遍历顺序和数组值语义也不是 <code class="notion-inline-code">for...in</code> 的设计重点。</div><div class="notion-text notion-block-69af3fb11a244b21a043a18f785e6fd5">需要数组值：</div><div class="notion-text notion-block-88765cd11f0d4f18b7132b45777cac39">需要索引和值：</div><div class="notion-text notion-block-a7c8a109effe4577a000c04f7607dc6d">需要支持 <code class="notion-inline-code">break</code>、<code class="notion-inline-code">continue</code> 或 <code class="notion-inline-code">await</code> 时，<code class="notion-inline-code">for...of</code> 通常比 <code class="notion-inline-code">.forEach()</code> 更合适。</div><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-6ed31d4b561244fbbd9549b665c423bc" data-id="6ed31d4b561244fbbd9549b665c423bc"><span><div id="6ed31d4b561244fbbd9549b665c423bc" class="notion-header-anchor"></div><a class="notion-hash-link" href="#6ed31d4b561244fbbd9549b665c423bc" title="3. splice、slice 与 toSpliced"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">3. <code class="notion-inline-code">splice</code>、<code class="notion-inline-code">slice</code> 与 <code class="notion-inline-code">toSpliced</code></span></span></h3><div class="notion-text notion-block-67899d282f5242768bc572afdb5af8b7">本章从「splice：修改原数组」「slice：提取浅拷贝，不修改原数组」和「toSpliced：不修改原数组的增删改」等方面说明 splice、slice 与 toSpliced。</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-b2a67d3bd27441cbacce35c94fffee21" data-id="b2a67d3bd27441cbacce35c94fffee21"><span><div id="b2a67d3bd27441cbacce35c94fffee21" class="notion-header-anchor"></div><a class="notion-hash-link" href="#b2a67d3bd27441cbacce35c94fffee21" title="3.1 splice：修改原数组"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">3.1 <code class="notion-inline-code">splice</code>：修改原数组</span></span></h4><div class="notion-text notion-block-a667578e78d442f78fa01da90ad8623e">签名：</div><div class="notion-text notion-block-c472f87e854045e3a3d3d26989ac4efd">返回被删除元素组成的新数组。</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-c03823ccd2824ede9626624eba9da71a" data-id="c03823ccd2824ede9626624eba9da71a"><span><div id="c03823ccd2824ede9626624eba9da71a" class="notion-header-anchor"></div><a class="notion-hash-link" href="#c03823ccd2824ede9626624eba9da71a" title="3.2 slice：提取浅拷贝，不修改原数组"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">3.2 <code class="notion-inline-code">slice</code>：提取浅拷贝，不修改原数组</span></span></h4><div class="notion-text notion-block-96d3491d5c99420eba7894ba398c8916">签名：</div><div class="notion-text notion-block-aef3d7343e9c41e4b0b55eea3ec39368">区间为左闭右开 <code class="notion-inline-code">[start, end)</code>。</div><div class="notion-text notion-block-9a02323c32ed4c298aaa41867602c253">“浅拷贝”意味着嵌套对象仍然共享引用：</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-f1971e7b6bc245289e991704dd5be5b3" data-id="f1971e7b6bc245289e991704dd5be5b3"><span><div id="f1971e7b6bc245289e991704dd5be5b3" class="notion-header-anchor"></div><a class="notion-hash-link" href="#f1971e7b6bc245289e991704dd5be5b3" title="3.3 toSpliced：不修改原数组的增删改"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">3.3 <code class="notion-inline-code">toSpliced</code>：不修改原数组的增删改</span></span></h4><div class="notion-text notion-block-6ae32e651a764cddb7fd6c9ccb643878">现代 JavaScript 提供 <code class="notion-inline-code">toSpliced</code>：</div><div class="notion-text notion-block-8ec3d862546242a492207277fcd63197">在 React 等强调不可变更新的场景中，<code class="notion-inline-code">toSpliced</code> 或展开运算符通常比直接 <code class="notion-inline-code">splice</code> 更安全。</div><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-79c4343b995943b0bdab2f335d7de8ce" data-id="79c4343b995943b0bdab2f335d7de8ce"><span><div id="79c4343b995943b0bdab2f335d7de8ce" class="notion-header-anchor"></div><a class="notion-hash-link" href="#79c4343b995943b0bdab2f335d7de8ce" title="4. 快速选择"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">4. 快速选择</span></span></h3><ul class="notion-list notion-list-disc notion-block-b645e0a1664246f6a8f26d6482d71804"><li>遍历对象键：<code class="notion-inline-code">Object.keys()</code>、<code class="notion-inline-code">Object.entries()</code> 或谨慎使用 <code class="notion-inline-code">for...in</code>。</li></ul><ul class="notion-list notion-list-disc notion-block-6a12486fa5844e9b83b0d0bfcb5bfa63"><li>遍历数组和集合值：<code class="notion-inline-code">for...of</code>。</li></ul><ul class="notion-list notion-list-disc notion-block-f10bd550b6c0447e81f202d9d179c62a"><li>需要索引：普通 <code class="notion-inline-code">for</code>、<code class="notion-inline-code">entries()</code> 或 <code class="notion-inline-code">.forEach()</code>。</li></ul><ul class="notion-list notion-list-disc notion-block-b09fc9f163af4ba288bc0aec0dc09b5c"><li>修改原数组并插入、删除、替换：<code class="notion-inline-code">splice</code>。</li></ul><ul class="notion-list notion-list-disc notion-block-e1450fbb9c1b459faa7fc570ffd5da4d"><li>截取子数组且不改原数组：<code class="notion-inline-code">slice</code>。</li></ul><ul class="notion-list notion-list-disc notion-block-23c2f95942204149925cca32b9bb65dc"><li>想使用 <code class="notion-inline-code">splice</code> 的语义但保持不可变：<code class="notion-inline-code">toSpliced</code>。</li></ul><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-6b82563b9190497aa3ace3fd5721b06b" data-id="6b82563b9190497aa3ace3fd5721b06b"><span><div id="6b82563b9190497aa3ace3fd5721b06b" class="notion-header-anchor"></div><a class="notion-hash-link" href="#6b82563b9190497aa3ace3fd5721b06b" title="5. 常见易错点"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">5. 常见易错点</span></span></h3><ul class="notion-list notion-list-disc notion-block-053030c18454424092bd674b053c0a02"><li><code class="notion-inline-code">typeof null</code> 返回 <code class="notion-inline-code">&quot;object&quot;</code>，不能用它判断 <code class="notion-inline-code">null</code>。</li></ul><ul class="notion-list notion-list-disc notion-block-79601f4964c04db5851705ad1ee79059"><li>数组也是对象，判断数组使用 <code class="notion-inline-code">Array.isArray</code>。</li></ul><ul class="notion-list notion-list-disc notion-block-2695685376d449739eb9a3dcfa25cc8f"><li><code class="notion-inline-code">for...in</code> 得到键，<code class="notion-inline-code">for...of</code> 得到迭代值。</li></ul><ul class="notion-list notion-list-disc notion-block-636460a66a6a4d4797282eb4881454ef"><li><code class="notion-inline-code">for...in</code> 可能遍历到继承的可枚举属性。</li></ul><ul class="notion-list notion-list-disc notion-block-a9ba8804a4c64bb7bc1feb46e020acb6"><li><code class="notion-inline-code">splice</code> 会修改原数组，<code class="notion-inline-code">slice</code> 不会。</li></ul><ul class="notion-list notion-list-disc notion-block-303d93456632458ea308ad86a9d449dc"><li><code class="notion-inline-code">slice</code> 是浅拷贝，不会递归复制嵌套对象。</li></ul><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-d646a455ebeb4dea81d467b2d85eef3f" data-id="d646a455ebeb4dea81d467b2d85eef3f"><span><div id="d646a455ebeb4dea81d467b2d85eef3f" class="notion-header-anchor"></div><a class="notion-hash-link" href="#d646a455ebeb4dea81d467b2d85eef3f" title="6. 总结"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">6. 总结</span></span></h3><div class="notion-text notion-block-e12123e8ecb6422188742b7927fbe440">JavaScript 中应先区分值的类型，再根据目标选择遍历和数组操作：对象键适合 <code class="notion-inline-code">Object.keys()</code>、<code class="notion-inline-code">Object.entries()</code> 或谨慎使用 <code class="notion-inline-code">for...in</code>，可迭代值适合 <code class="notion-inline-code">for...of</code>；需要原地修改数组时使用 <code class="notion-inline-code">splice</code>，需要新数组时使用 <code class="notion-inline-code">slice</code> 或 <code class="notion-inline-code">toSpliced</code>。</div><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-6bfe2f2daefe4bf6a89202d776a120b1" data-id="6bfe2f2daefe4bf6a89202d776a120b1"><span><div id="6bfe2f2daefe4bf6a89202d776a120b1" class="notion-header-anchor"></div><a class="notion-hash-link" href="#6bfe2f2daefe4bf6a89202d776a120b1" title="7. 官方参考"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">7. 官方参考</span></span></h3><ul class="notion-list notion-list-disc notion-block-ed32a04642274ba8b575a4ad2de46f34"><li><a class="notion-link" href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Data_structures" target="_blank" rel="noopener noreferrer">MDN：JavaScript 数据类型与数据结构</a></li></ul><ul class="notion-list notion-list-disc notion-block-111f9c1665ea49c3bbac6f949b1774ef"><li><a class="notion-link" href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...in" target="_blank" rel="noopener noreferrer">MDN：for-in 语句</a></li></ul><ul class="notion-list notion-list-disc notion-block-9ea7e0c5885d47ac893fe398ae7a37c0"><li><a class="notion-link" href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...of" target="_blank" rel="noopener noreferrer">MDN：for-of 语句</a></li></ul><ul class="notion-list notion-list-disc notion-block-35a85fa0d599475f8971c6134b9d1f94"><li><a class="notion-link" href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/splice" target="_blank" rel="noopener noreferrer">MDN：Array.prototype.splice</a></li></ul><ul class="notion-list notion-list-disc notion-block-dd4b9726cf8040a7a193da0b16a4edff"><li><a class="notion-link" href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/slice" target="_blank" rel="noopener noreferrer">MDN：Array.prototype.slice</a></li></ul></main></div>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[C++ 学习笔记]]></title>
            <link>https://www.yyshow.xyz/article/cpp-study-notes</link>
            <guid>https://www.yyshow.xyz/article/cpp-study-notes</guid>
            <pubDate>Sat, 12 Jul 2025 00:00:00 GMT</pubDate>
            <description><![CDATA[系统整理现代 C++ 的类型、字符串、函数、指针与引用、对象生命周期、RAII、多态、拷贝移动、模板、STL、tuple、异常和工程实践。]]></description>
            <content:encoded><![CDATA[<div id="notion-article" class="mx-auto overflow-hidden "><main class="notion light-mode notion-page notion-block-399560c488bc8184802cd6942d769265"><div class="notion-viewport"></div><div class="notion-collection-page-properties"></div><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-f32f2cc38a094c6b9289883a611d854b" data-id="f32f2cc38a094c6b9289883a611d854b"><span><div id="f32f2cc38a094c6b9289883a611d854b" class="notion-header-anchor"></div><a class="notion-hash-link" href="#f32f2cc38a094c6b9289883a611d854b" title="1. 程序结构与类型系统"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">1. 程序结构与类型系统</span></span></h3><div class="notion-text notion-block-f0dab112d3fe4df89d284fbda3139d99">本章从「C++ 程序的基本结构」「基本数据类型」和「初始化与类型推导」等方面说明程序结构与类型系统。</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-5428c320669345a3a3ec2a4f3aa489e0" data-id="5428c320669345a3a3ec2a4f3aa489e0"><span><div id="5428c320669345a3a3ec2a4f3aa489e0" class="notion-header-anchor"></div><a class="notion-hash-link" href="#5428c320669345a3a3ec2a4f3aa489e0" title="1.1 C++ 程序的基本结构"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">1.1 C++ 程序的基本结构</span></span></h4><div class="notion-text notion-block-2a7198b73f4c46fc871a7a1528b6f334">一个最小的 C++ 程序由头文件、函数和语句组成：</div><ul class="notion-list notion-list-disc notion-block-81085eafca3245d889217acbfd2e0330"><li><code class="notion-inline-code">#include &lt;iostream&gt;</code> 引入标准输入输出相关声明。</li></ul><ul class="notion-list notion-list-disc notion-block-d7fe2d9f217d44cc840ba266b7b20590"><li><code class="notion-inline-code">main</code> 是程序入口。</li></ul><ul class="notion-list notion-list-disc notion-block-eb5ef930283341eca88b25746c8dc16b"><li><code class="notion-inline-code">std::cout</code> 表示标准输出流。</li></ul><ul class="notion-list notion-list-disc notion-block-d8279140f67443478b92c5a64691d974"><li><code class="notion-inline-code">return 0</code> 表示程序正常结束。</li></ul><div class="notion-text notion-block-3c62e207c5604e38b5795cae92a94ad4">源文件通常经过预处理、编译、汇编和链接后生成可执行文件：</div><div class="notion-text notion-block-e81c0d22005f419db4dbb3bf1b03226e">头文件主要保存声明，源文件保存定义。模板、<code class="notion-inline-code">inline</code> 函数和部分编译期代码通常需要在头文件中提供完整定义，因为编译器必须在实例化位置看到实现。</div><h5 class="notion-h notion-h4 notion-h-indent-2 notion-block-cb0b792e639443c3b7a42a87c727b2de" data-id="cb0b792e639443c3b7a42a87c727b2de"><span><div id="cb0b792e639443c3b7a42a87c727b2de" class="notion-header-anchor"></div><a class="notion-hash-link" href="#cb0b792e639443c3b7a42a87c727b2de" title="1.1.1 命名空间"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">1.1.1 命名空间</span></span></h5><div class="notion-text notion-block-193dd5e9d6524d8bb0e2e41a72d4f590">标准库名称位于 <code class="notion-inline-code">std</code> 命名空间中：</div><div class="notion-text notion-block-55b341388f0b425ba5a567665fb407b1"><code class="notion-inline-code">using namespace std;</code> 会把整个命名空间引入当前作用域，容易造成名称冲突。头文件中应避免使用这种写法；规模较大的项目也更适合明确写出 <code class="notion-inline-code">std::</code>。</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-e57a3b97f2ee44f7a4ee489faf48b323" data-id="e57a3b97f2ee44f7a4ee489faf48b323"><span><div id="e57a3b97f2ee44f7a4ee489faf48b323" class="notion-header-anchor"></div><a class="notion-hash-link" href="#e57a3b97f2ee44f7a4ee489faf48b323" title="1.2 基本数据类型"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">1.2 基本数据类型</span></span></h4><div class="notion-text notion-block-67f6146e2f3145a7a86cd324023aa263">C++ 的基础类型包括布尔、字符、整数和浮点数：</div><div class="notion-text notion-block-a4e680ed487d400a8565272065bcd415">不同平台对部分类型的宽度规定不同。<code class="notion-inline-code">sizeof</code> 返回对象或类型占用的字节数：</div><div class="notion-text notion-block-7f30b70f21fa4558bfec9471952708c5">需要固定宽度整数时，可以使用 <code class="notion-inline-code">&lt;cstdint&gt;</code> 中的类型：</div><blockquote class="notion-quote notion-block-e312c04d7616487892ab434ed441c358"><div><code class="notion-inline-code">sizeof</code> 的单位是字节。<code class="notion-inline-code">long</code>、指针和其他实现相关类型的宽度不能脱离目标平台直接写死。</div></blockquote><h5 class="notion-h notion-h4 notion-h-indent-2 notion-block-52b387c35d5e4b2db544de4f7b95f936" data-id="52b387c35d5e4b2db544de4f7b95f936"><span><div id="52b387c35d5e4b2db544de4f7b95f936" class="notion-header-anchor"></div><a class="notion-hash-link" href="#52b387c35d5e4b2db544de4f7b95f936" title="1.2.1 有符号与无符号整数"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">1.2.1 有符号与无符号整数</span></span></h5><div class="notion-text notion-block-ef68c977d06b4926bee6c4a3178c568d">有符号整数可以表示负数；无符号整数只表示非负值。无符号整数运算按模 <span role="button" tabindex="0" class="notion-equation notion-equation-inline"><span></span></span> 回绕，有符号整数溢出属于未定义行为。</div><div class="notion-text notion-block-ca0bb05767d84b04a13b12efd22ae89e">位标记更适合使用无符号整数：</div><div class="notion-text notion-block-7840b65a6eda473189ea9976270c9154">循环下标、容器长度和有符号整数混合比较时，容易触发隐式转换。无法确认类型范围时，应先统一类型，再执行比较。</div><h5 class="notion-h notion-h4 notion-h-indent-2 notion-block-26c90636d4f442619249f7610074bc3f" data-id="26c90636d4f442619249f7610074bc3f"><span><div id="26c90636d4f442619249f7610074bc3f" class="notion-header-anchor"></div><a class="notion-hash-link" href="#26c90636d4f442619249f7610074bc3f" title="1.2.2 浮点数精度"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">1.2.2 浮点数精度</span></span></h5><div class="notion-text notion-block-7f007c3b898745098c237046f76e880f">许多十进制小数不能被有限二进制位精确表示，因此浮点计算通常不直接使用 <code class="notion-inline-code">==</code> 判断结果：</div><div class="notion-text notion-block-ef5d52e3bff34aaca851d36ed14e975a">固定误差适合数值范围稳定的场景。数值跨度较大时，还需要结合相对误差判断。</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-c71bd837d0d844abb8cb4e92bd9d5683" data-id="c71bd837d0d844abb8cb4e92bd9d5683"><span><div id="c71bd837d0d844abb8cb4e92bd9d5683" class="notion-header-anchor"></div><a class="notion-hash-link" href="#c71bd837d0d844abb8cb4e92bd9d5683" title="1.3 初始化与类型推导"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">1.3 初始化与类型推导</span></span></h4><div class="notion-text notion-block-2ca98595ccf749218b7b8566d86bfe4f">C++ 支持多种初始化形式：</div><div class="notion-text notion-block-8a30da47f12a4012b21c12961b0490bd">{}花括号初始化能够阻止部分窄化转换：</div><div class="notion-text notion-block-97485be8f9644f8c93b9bf0735767c02">局部基础类型未初始化时，其值通常不确定：</div><div class="notion-text notion-block-766146a8d3054d4c928bc3ab0da18369"><code class="notion-inline-code">auto</code> 根据初始化表达式推导类型：</div><div class="notion-text notion-block-368b94523173435fa86e0dee7e61f895"><code class="notion-inline-code">auto</code> 会忽略顶层 <code class="notion-inline-code">const</code> 和引用属性。需要保留引用或常量语义时，应明确写出：</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-b1dead7246914e918356fa9a0d5e4e42" data-id="b1dead7246914e918356fa9a0d5e4e42"><span><div id="b1dead7246914e918356fa9a0d5e4e42" class="notion-header-anchor"></div><a class="notion-hash-link" href="#b1dead7246914e918356fa9a0d5e4e42" title="1.4 const 与 constexpr"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">1.4 <code class="notion-inline-code">const</code> 与 <code class="notion-inline-code">constexpr</code></span></span></h4><div class="notion-text notion-block-f7a89759be454e188ff0017b5bfd4799"><code class="notion-inline-code">const</code> 表示对象不能通过当前访问路径被修改：</div><div class="notion-text notion-block-1c35d8a2ec6f44db8a23c718059c1feb"><code class="notion-inline-code">constexpr</code> 表示对象或函数可以参与常量表达式求值：</div><div class="notion-text notion-block-58cdc48ed6ab47379a59782ce63cf838"><code class="notion-inline-code">constexpr</code> 变量同时具有 <code class="notion-inline-code">const</code> 属性。<code class="notion-inline-code">constexpr</code> 函数在参数满足常量表达式要求时可在编译期求值，也可以在运行期调用。</div><div class="notion-text notion-block-ac062c688aa44924aafcddc2a9e84c56">成员函数末尾的 <code class="notion-inline-code">const</code> 表示该函数不修改对象的可观察状态：</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-e4d40eb6cd3e4f499be773f462125c5c" data-id="e4d40eb6cd3e4f499be773f462125c5c"><span><div id="e4d40eb6cd3e4f499be773f462125c5c" class="notion-header-anchor"></div><a class="notion-hash-link" href="#e4d40eb6cd3e4f499be773f462125c5c" title="1.5 运算符与表达式"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">1.5 运算符与表达式</span></span></h4><div class="notion-text notion-block-81da1fe6c7494f31b94448d9e37e7220">整数除法会舍弃小数部分：</div><div class="notion-text notion-block-0bd52b9f01f74d4882d867bcd4420ba0">逻辑运算符 <code class="notion-inline-code">&amp;&amp;</code> 和 <code class="notion-inline-code">||</code> 具有短路行为：</div><div class="notion-text notion-block-eecf3226e41446ffb89c9b9dbf260dac">只有左侧条件满足继续计算的要求时，右侧表达式才会执行。</div><div class="notion-text notion-block-33641831c2664f4a8f90ba49423cf129">常用位运算符包括：</div><ul class="notion-list notion-list-disc notion-block-43c021a193b244d4b26c551e895c5bc7"><li><code class="notion-inline-code">&amp;</code>：按位与；</li></ul><ul class="notion-list notion-list-disc notion-block-152e06a3d1024aba8ab62abc1f0000ab"><li><code class="notion-inline-code">|</code>：按位或；</li></ul><ul class="notion-list notion-list-disc notion-block-747fc3ac3b4e4d2fb4fe676ca5b1f284"><li><code class="notion-inline-code">^</code>：按位异或；</li></ul><ul class="notion-list notion-list-disc notion-block-a24fcbb58acc43b8a005621de9e4eb8b"><li><code class="notion-inline-code">~</code>：按位取反；</li></ul><ul class="notion-list notion-list-disc notion-block-665b9aabf9964db2a1ba0fe84e695614"><li><code class="notion-inline-code">&lt;&lt;</code>：左移；</li></ul><ul class="notion-list notion-list-disc notion-block-5546f180a88946be897fe22d68eccea4"><li><code class="notion-inline-code">&gt;&gt;</code>：右移。</li></ul><div class="notion-text notion-block-678ca557783b43ef8f34b763bd0f21c6">位运算优先使用无符号类型，并避免移位位数超出类型宽度。</div><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-6ecd0a4cbaa54d9ab15fc97b4ddff6f8" data-id="6ecd0a4cbaa54d9ab15fc97b4ddff6f8"><span><div id="6ecd0a4cbaa54d9ab15fc97b4ddff6f8" class="notion-header-anchor"></div><a class="notion-hash-link" href="#6ecd0a4cbaa54d9ab15fc97b4ddff6f8" title="2. 字符串"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">2. 字符串</span></span></h3><div class="notion-text notion-block-0a6cafa7aff244b48818e3005840c260">本章从「C 风格字符串」「std::string」和「字符串与数字转换」等方面说明字符串。</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-ab036b300cf6468fb09f040ec9ed485f" data-id="ab036b300cf6468fb09f040ec9ed485f"><span><div id="ab036b300cf6468fb09f040ec9ed485f" class="notion-header-anchor"></div><a class="notion-hash-link" href="#ab036b300cf6468fb09f040ec9ed485f" title="2.1 C 风格字符串"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">2.1 C 风格字符串</span></span></h4><div class="notion-text notion-block-63e749a9db9443a4ae67a1c285bc94cc">C 风格字符串是以空字符 <code class="notion-inline-code">\0</code> 结尾的字符序列：</div><div class="notion-text notion-block-4f0d850cb097486abdd136718931d555">内存中实际保存：</div><div class="notion-text notion-block-1087bb3a1ab34377a09aa06a71aa5781">字符串字面量不应被修改：</div><div class="notion-text notion-block-9615aaed511247bdade1c07a6af5dbba">如果强行去掉 <code class="notion-inline-code">const</code> 并尝试修改字符串字面量，程序行为未定义。需要可修改的字符序列时，可以使用字符数组：</div><div class="notion-text notion-block-e4f4af88606b4e3998b348cda2da7c03"><code class="notion-inline-code">&lt;cstring&gt;</code> 提供常见 C 字符串函数：</div><div class="notion-text notion-block-023015ac69a4494a8700e36194d100d3"><code class="notion-inline-code">strcpy</code> 和 <code class="notion-inline-code">strcat</code> 依赖调用者保证目标缓冲区空间充足。空间不足会造成越界写入。普通 C++ 业务代码优先使用 <code class="notion-inline-code">std::string</code>，C 风格字符串主要用于兼容 C 接口、底层库和固定格式缓冲区。</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-3c5dc3fa839b48aba7fdc5a8feeb40e6" data-id="3c5dc3fa839b48aba7fdc5a8feeb40e6"><span><div id="3c5dc3fa839b48aba7fdc5a8feeb40e6" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3c5dc3fa839b48aba7fdc5a8feeb40e6" title="2.2 std::string"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">2.2 <code class="notion-inline-code">std::string</code></span></span></h4><div class="notion-text notion-block-5bf58fa0ee30410e81e261c0ebe2360b"><code class="notion-inline-code">std::string</code> 管理字符存储和生命周期，支持拼接、查找、插入和删除：</div><div class="notion-text notion-block-f5d181dcba5543678ee58f8547875c4e">常用接口：</div><div class="notion-text notion-block-cc082b5617794305ae59ef123a784a91">字符访问方式：</div><ul class="notion-list notion-list-disc notion-block-3a05dba70f3c4dcf8d935c272336e0f2"><li><code class="notion-inline-code">operator[]</code> 不执行边界检查；</li></ul><ul class="notion-list notion-list-disc notion-block-9d6892a18d7845b2ae95327bd176c399"><li><code class="notion-inline-code">at</code> 越界时抛出 <code class="notion-inline-code">std::out_of_range</code>；</li></ul><ul class="notion-list notion-list-disc notion-block-eabe18c91bb04bc18db1cd0b10a43e6b"><li><code class="notion-inline-code">size()</code> 和 <code class="notion-inline-code">length()</code> 对 <code class="notion-inline-code">std::string</code> 等价。</li></ul><div class="notion-text notion-block-a624290fd68c460baf000c0bca115235"><code class="notion-inline-code">size</code> 表示当前字符数量，<code class="notion-inline-code">capacity</code> 表示已经分配的容量：</div><div class="notion-text notion-block-de6a5346190749b99adc82c97061d6aa"><code class="notion-inline-code">shrink_to_fit</code> 是非强制请求，标准库实现可以选择不缩容。</div><div class="notion-text notion-block-2e635bb4de72453eb457971ea554d5c7">与 C 接口协作时，可以通过 <code class="notion-inline-code">c_str()</code> 取得以 <code class="notion-inline-code">\0</code> 结尾的只读字符指针：</div><div class="notion-text notion-block-e06d8d8f5876447282167e4e6214f44e">字符串发生修改或重新分配后，之前取得的指针可能失效。</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-6372d636f2b648ee9fb4af30522729cf" data-id="6372d636f2b648ee9fb4af30522729cf"><span><div id="6372d636f2b648ee9fb4af30522729cf" class="notion-header-anchor"></div><a class="notion-hash-link" href="#6372d636f2b648ee9fb4af30522729cf" title="2.3 字符串与数字转换"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">2.3 字符串与数字转换</span></span></h4><div class="notion-text notion-block-e086457f69f04f308fd0057a7676e842">输入格式错误或数值超出范围时，<code class="notion-inline-code">stoi</code>、<code class="notion-inline-code">stoll</code> 和 <code class="notion-inline-code">stod</code> 会抛出异常。处理大量不可信文本或性能敏感的解析时，可以使用 <code class="notion-inline-code">&lt;charconv&gt;</code> 中的 <code class="notion-inline-code">std::from_chars</code>。</div><div class="notion-blank notion-block-39a560c488bc803081c2e1909e7e07af"> </div><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-39a560c488bc8080af00e524fed1abc4" data-id="39a560c488bc8080af00e524fed1abc4"><span><div id="39a560c488bc8080af00e524fed1abc4" class="notion-header-anchor"></div><a class="notion-hash-link" href="#39a560c488bc8080af00e524fed1abc4" title="3. 函数与参数传递"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">3. 函数与参数传递</span></span></h3><div class="notion-text notion-block-f2ba79cf99e14429aa6bc3b046ddda07">本章从「不同类型的参数传递」和「函数重载」两方面说明函数与参数传递。</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-39a560c488bc80d49d1bd954d1b6a2d1" data-id="39a560c488bc80d49d1bd954d1b6a2d1"><span><div id="39a560c488bc80d49d1bd954d1b6a2d1" class="notion-header-anchor"></div><a class="notion-hash-link" href="#39a560c488bc80d49d1bd954d1b6a2d1" title="3.1 不同类型的参数传递"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">3.1 不同类型的参数传递</span></span></h4><div class="notion-text notion-block-f231e35586274c019e8cd595d28f067f">按值传递会创建参数副本：</div><div class="notion-text notion-block-6378806412364208b38584f1123978bd">引用参数直接绑定到调用者对象：</div><div class="notion-text notion-block-c3dc743b212e4b2b9b4c07f196a6ea7c">较大的只读对象通常使用常量引用传递：</div><div class="notion-text notion-block-5f7695d277c8483f89ef5d2f90837752">指针适合表达“对象可能不存在”或需要与底层接口交互的场景：</div><div class="notion-text notion-block-a765df867ec74f5e88af958573e1a48a">选择参数形式时，可以先判断两个问题：</div><ol start="1" class="notion-list notion-list-numbered notion-block-988daa4c994f45c68d2a9fd84d8bb7f1" style="list-style-type:decimal"><li>函数是否需要修改实参？</li></ol><ol start="2" class="notion-list notion-list-numbered notion-block-b8e956d5bcee42baae606a19a88f98cb" style="list-style-type:decimal"><li>“没有对象”是否属于合法状态？</li></ol><table class="notion-simple-table notion-block-c0d66ab290e546febbd305da1a502be9"><tbody><tr class="notion-simple-table-row notion-simple-table-header-row notion-block-f71e1d552ea2433dbab76edc149121cb"><td class="" style="width:120px"><div class="notion-simple-table-cell">需求</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">推荐形式</div></td></tr><tr class="notion-simple-table-row notion-block-14563177fe0146c58f332ec97b223724"><td class="" style="width:120px"><div class="notion-simple-table-cell">小型只读值</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">按值传递 <code class="notion-inline-code">T</code></div></td></tr><tr class="notion-simple-table-row notion-block-cb991884034f4388908114ff322b671a"><td class="" style="width:120px"><div class="notion-simple-table-cell">大型只读对象</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">常量引用 <code class="notion-inline-code">const T&amp;</code></div></td></tr><tr class="notion-simple-table-row notion-block-5dec7cdc4cae4ca8be7477b0406b07a9"><td class="" style="width:120px"><div class="notion-simple-table-cell">必须存在且需要修改</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">引用 <code class="notion-inline-code">T&amp;</code></div></td></tr><tr class="notion-simple-table-row notion-block-ddffeb1dfe5d4027a62dc7cb4ad841dd"><td class="" style="width:120px"><div class="notion-simple-table-cell">允许为空且不转移所有权</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">指针 <code class="notion-inline-code">T*</code></div></td></tr><tr class="notion-simple-table-row notion-block-cee52c0a68e248f69c78088e3bc78590"><td class="" style="width:120px"><div class="notion-simple-table-cell">需要取得所有权</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">智能指针或按值接收资源对象</div></td></tr></tbody></table><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-39a560c488bc802f9376f4e29a419991" data-id="39a560c488bc802f9376f4e29a419991"><span><div id="39a560c488bc802f9376f4e29a419991" class="notion-header-anchor"></div><a class="notion-hash-link" href="#39a560c488bc802f9376f4e29a419991" title="3.2 函数重载"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">3.2 函数重载</span></span></h4><div class="notion-text notion-block-39a560c488bc8000a9ffe8a875173052">同一作用域中，函数可以通过不同参数列表形成重载：</div><div class="notion-text notion-block-39a560c488bc806da11df402d6b51b88">返回类型不能单独构成重载。默认参数与函数重载同时使用时，需要检查调用是否产生二义性。</div><div class="notion-blank notion-block-39a560c488bc802f9628e6a9ee4e9501"> </div><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-dd3513990be64cafb53a9fd521d63002" data-id="dd3513990be64cafb53a9fd521d63002"><span><div id="dd3513990be64cafb53a9fd521d63002" class="notion-header-anchor"></div><a class="notion-hash-link" href="#dd3513990be64cafb53a9fd521d63002" title="4. 指针与引用"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">4. 指针与引用</span></span></h3><div class="notion-text notion-block-588d1015de7247aaa82d089ff0ca5df7">指针保存对象地址，可以为空，也可以重新指向其他对象：</div><div class="notion-text notion-block-9e21f61082b74dcebdfe4a713125b7ff">引用是已有对象的别名，声明时必须绑定对象，之后不能改为绑定另一个对象：</div><div class="notion-text notion-block-2994068bd6794e838716e09abc29f19e">指针和引用的主要区别：</div><ul class="notion-list notion-list-disc notion-block-cdca280c9ff344a799fece5b5ac9a586"><li>指针存在 <code class="notion-inline-code">nullptr</code> 状态，引用在正常语言语义中必须绑定有效对象；</li></ul><ul class="notion-list notion-list-disc notion-block-799dbdcfa40a4772af1f684998f36f56"><li>指针可以重新赋值为另一个地址，引用不能重新绑定；</li></ul><ul class="notion-list notion-list-disc notion-block-4b48310014d64dabbfa3240f795eeb50"><li>指针通过 <code class="notion-inline-code">*</code> 和 <code class="notion-inline-code">-&gt;</code> 访问目标，引用按对象语法使用；</li></ul><ul class="notion-list notion-list-disc notion-block-0ebc37f9473d4166b6a55f50e2cb0267"><li>裸指针和引用通常只表达访问关系，不自动说明资源所有权。</li></ul><blockquote class="notion-quote notion-block-086281f504ba4a98b34515874b708b93"><div>不要把“引用一定不占内存”当作语言规则。编译器可以根据实现需要为引用保留存储，程序应只依赖引用的语言语义。</div></blockquote><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-1532de4f0d8f4c8a83781c7369095814" data-id="1532de4f0d8f4c8a83781c7369095814"><span><div id="1532de4f0d8f4c8a83781c7369095814" class="notion-header-anchor"></div><a class="notion-hash-link" href="#1532de4f0d8f4c8a83781c7369095814" title="4.1 nullptr"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">4.1 <code class="notion-inline-code">nullptr</code></span></span></h4><div class="notion-text notion-block-da261da5546547da9a2a89b5311808c9">现代 C++ 使用 <code class="notion-inline-code">nullptr</code> 表示空指针：</div><div class="notion-text notion-block-290a0dbb42ba4af8be6bd040f1ebeb15"><code class="notion-inline-code">nullptr</code> 具有专门的空指针类型，可以避免 <code class="notion-inline-code">NULL</code> 被当成整数常量后引发重载歧义。</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-aadfa7522795440588c2d710bb189ff4" data-id="aadfa7522795440588c2d710bb189ff4"><span><div id="aadfa7522795440588c2d710bb189ff4" class="notion-header-anchor"></div><a class="notion-hash-link" href="#aadfa7522795440588c2d710bb189ff4" title="4.2 指向常量的指针与常量指针"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">4.2 指向常量的指针与常量指针</span></span></h4><ul class="notion-list notion-list-disc notion-block-b95470673b754714a987224368dd5e95"><li><code class="notion-inline-code">const int*</code>：不能通过该指针修改目标，指针本身可以改指向；</li></ul><ul class="notion-list notion-list-disc notion-block-d4bbc99c449b4682b80ebb45d11b9fdb"><li><code class="notion-inline-code">int* const</code>：指针本身不能改指向，可以修改目标；</li></ul><ul class="notion-list notion-list-disc notion-block-41d3a690267b42fa95403617ce587f55"><li><code class="notion-inline-code">const int* const</code>：指针和目标访问权限都受限。</li></ul><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-39a560c488bc80af8e2bd7e7ee0d5aef" data-id="39a560c488bc80af8e2bd7e7ee0d5aef"><span><div id="39a560c488bc80af8e2bd7e7ee0d5aef" class="notion-header-anchor"></div><a class="notion-hash-link" href="#39a560c488bc80af8e2bd7e7ee0d5aef" title="4.3 智能指针"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">4.3 智能指针</span></span></h4><h5 class="notion-h notion-h4 notion-h-indent-2 notion-block-0f8c7b9c65064fe292bebdcc326c62e0" data-id="0f8c7b9c65064fe292bebdcc326c62e0"><span><div id="0f8c7b9c65064fe292bebdcc326c62e0" class="notion-header-anchor"></div><a class="notion-hash-link" href="#0f8c7b9c65064fe292bebdcc326c62e0" title="4.3.1 std::unique_ptr"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">4.3.1 <code class="notion-inline-code">std::unique_ptr</code></span></span></h5><div class="notion-text notion-block-39a560c488bc80eda376d16e4a5805c7"><code class="notion-inline-code">unique_ptr</code> 表示独占所有权，不能复制，只能移动：</div><div class="notion-text notion-block-39a560c488bc8000be88d115ad3f3dcc">独占关系能够成立时，优先使用 <code class="notion-inline-code">unique_ptr</code>。它的所有者明确，生命周期容易判断。</div><h5 class="notion-h notion-h4 notion-h-indent-2 notion-block-39a560c488bc809dbbb1ecac2c2a04e3" data-id="39a560c488bc809dbbb1ecac2c2a04e3"><span><div id="39a560c488bc809dbbb1ecac2c2a04e3" class="notion-header-anchor"></div><a class="notion-hash-link" href="#39a560c488bc809dbbb1ecac2c2a04e3" title="4.3.2 std::shared_ptr"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">4.3.2 <code class="notion-inline-code">std::shared_ptr</code></span></span></h5><div class="notion-text notion-block-39a560c488bc8026bc85cb99bdefd5d7"><code class="notion-inline-code">shared_ptr</code> 使用引用计数表示共享所有权：</div><div class="notion-text notion-block-39a560c488bc8065bf6ac97eb5b245fd">最后一个拥有者销毁时，对象才会释放。共享所有权会增加控制块、引用计数和并发访问相关开销，不应仅为“避免思考生命周期”而使用。</div><h5 class="notion-h notion-h4 notion-h-indent-2 notion-block-39a560c488bc80c9afc9d34527054b31" data-id="39a560c488bc80c9afc9d34527054b31"><span><div id="39a560c488bc80c9afc9d34527054b31" class="notion-header-anchor"></div><a class="notion-hash-link" href="#39a560c488bc80c9afc9d34527054b31" title="4.3.3 std::weak_ptr"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">4.3.3 <code class="notion-inline-code">std::weak_ptr</code></span></span></h5><div class="notion-text notion-block-39a560c488bc80f29f4ae1dd4b9e4a30"><code class="notion-inline-code">weak_ptr</code> 观察 <code class="notion-inline-code">shared_ptr</code> 管理的对象，但不增加强引用计数。它常用于打破循环引用：</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-39a560c488bc8087b42af93b4d1432c9" data-id="39a560c488bc8087b42af93b4d1432c9"><span><div id="39a560c488bc8087b42af93b4d1432c9" class="notion-header-anchor"></div><a class="notion-hash-link" href="#39a560c488bc8087b42af93b4d1432c9" title="4.4 悬空引用与失效规则"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">4.4 悬空引用与失效规则</span></span></h4><div class="notion-text notion-block-39a560c488bc8071bda4cddb16c3eecd">以下情况容易产生悬空指针或悬空引用：</div><ul class="notion-list notion-list-disc notion-block-39a560c488bc80749bbed1093ec91245"><li>返回局部变量的地址或引用；</li></ul><ul class="notion-list notion-list-disc notion-block-39a560c488bc801181bdc8bbb3031908"><li>对象销毁后继续访问其成员；</li></ul><ul class="notion-list notion-list-disc notion-block-39a560c488bc80cfb940cb3059ceaf06"><li>容器扩容后继续使用旧迭代器、指针或引用；</li></ul><ul class="notion-list notion-list-disc notion-block-39a560c488bc801db08ae8af882e846c"><li>移动、交换或删除对象后仍假设原地址关系不变；</li></ul><ul class="notion-list notion-list-disc notion-block-39a560c488bc80fb9a29c99fa7d4db56"><li>异步任务保存了生命周期不足的捕获对象。</li></ul><div class="notion-text notion-block-39a560c488bc80c9b62af4bdfbc9bc84">错误示例：</div><div class="notion-text notion-block-39a560c488bc801e9e5edbd05f61da77">调用者得到的引用在函数返回后已经失效。应按值返回，或返回生命周期覆盖调用范围的对象引用。</div><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-c4989d2abf4c4e5999c5421873089170" data-id="c4989d2abf4c4e5999c5421873089170"><span><div id="c4989d2abf4c4e5999c5421873089170" class="notion-header-anchor"></div><a class="notion-hash-link" href="#c4989d2abf4c4e5999c5421873089170" title="5. 对象生命周期与资源管理"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">5. 对象生命周期与资源管理</span></span></h3><div class="notion-text notion-block-924fc6d508024021b22bb3d7622e923a">本章从「存储期与对象生命周期」「new 与 delete」和「RAII」等方面说明对象生命周期与资源管理。</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-c8124583e93a44c6a02b467d6f03f6e8" data-id="c8124583e93a44c6a02b467d6f03f6e8"><span><div id="c8124583e93a44c6a02b467d6f03f6e8" class="notion-header-anchor"></div><a class="notion-hash-link" href="#c8124583e93a44c6a02b467d6f03f6e8" title="5.1 存储期与对象生命周期"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">5.1 存储期与对象生命周期</span></span></h4><div class="notion-text notion-block-2363d65dabb243d49bd5a29eac12504d">存储期描述对象所占存储空间存在多久；生命周期描述对象从构造完成到析构开始的有效时间。两者相关，但不能完全等同。</div><div class="notion-text notion-block-b516ad53b3cf479cb8f8173d62ce3ac7">常见存储期包括：</div><ol start="1" class="notion-list notion-list-numbered notion-block-bdab264fcbea4adf8aadb13e89f1cf0f" style="list-style-type:decimal"><li><b>自动存储期：</b>局部对象通常在进入作用域时创建，离开作用域时销毁。</li></ol><ol start="2" class="notion-list notion-list-numbered notion-block-4127d338f85147bbac54b9eb728c4682" style="list-style-type:decimal"><li><b>静态存储期：</b>全局对象、命名空间对象和静态局部对象通常存活到程序结束。</li></ol><ol start="3" class="notion-list notion-list-numbered notion-block-87d1d445a858426f9330f34e29820d91" style="list-style-type:decimal"><li><b>线程存储期：</b><code class="notion-inline-code">thread_local</code> 对象与线程生命周期关联。</li></ol><ol start="4" class="notion-list notion-list-numbered notion-block-d2eacfc85c7b4050858dffccc1dfaa8b" style="list-style-type:decimal"><li><b>动态存储期：</b>通过动态分配获得，由程序或资源管理对象控制释放时机。</li></ol><div class="notion-text notion-block-650c59e3ee634a79802a083277e33471">工程中常说的“栈、堆、全局区”便于理解典型实现，但 C++ 标准主要规定对象语义和存储期，不强制所有实现采用完全相同的物理内存布局。</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-49f1aa9b23e4471e9def4fdd3d1c039d" data-id="49f1aa9b23e4471e9def4fdd3d1c039d"><span><div id="49f1aa9b23e4471e9def4fdd3d1c039d" class="notion-header-anchor"></div><a class="notion-hash-link" href="#49f1aa9b23e4471e9def4fdd3d1c039d" title="5.2 new 与 delete"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">5.2 <code class="notion-inline-code">new</code> 与 <code class="notion-inline-code">delete</code></span></span></h4><div class="notion-text notion-block-a33103b6cedc42e4a7223d99951ff361">动态创建单个对象：</div><div class="notion-text notion-block-b67b783691c34e3bb1e2b8dd7d0fead1">动态数组必须配对使用 <code class="notion-inline-code">new[]</code> 和 <code class="notion-inline-code">delete[]</code>：</div><div class="notion-text notion-block-3a8aec44c2d14f2591259c18f264447d">常见错误包括：</div><ul class="notion-list notion-list-disc notion-block-54f3fd5c10ec4e1b96c90bacc9d83add"><li>忘记释放，造成资源泄漏；</li></ul><ul class="notion-list notion-list-disc notion-block-4ec78110751d457aad7088e900603074"><li>重复释放同一地址；</li></ul><ul class="notion-list notion-list-disc notion-block-56f88fce1547415999750f7aaedf0fac"><li>使用错误的 <code class="notion-inline-code">delete</code> 形式；</li></ul><ul class="notion-list notion-list-disc notion-block-82ef7297993540d2b76119408ff6162f"><li>释放后继续访问悬空指针；</li></ul><ul class="notion-list notion-list-disc notion-block-dc8d6e8544874ae8b6144f0c5c7d64c1"><li>一个地址由多个对象同时负责释放。</li></ul><div class="notion-text notion-block-4ce62a1466554034aacbbd4feffe16df">把某个指针设为 <code class="notion-inline-code">nullptr</code> 只能防止继续通过该变量访问旧地址，不能使其他别名指针自动失效。</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-8f607bffa2fc45a5bb9f095534d90b61" data-id="8f607bffa2fc45a5bb9f095534d90b61"><span><div id="8f607bffa2fc45a5bb9f095534d90b61" class="notion-header-anchor"></div><a class="notion-hash-link" href="#8f607bffa2fc45a5bb9f095534d90b61" title="5.3 RAII"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">5.3 RAII</span></span></h4><div class="notion-text notion-block-a42a16dbb6c34b33b628088605eb1be3">RAII 将资源的获取和释放绑定到对象生命周期。构造函数建立资源所有权，析构函数负责释放资源。作用域结束、提前返回或异常传播时，局部对象都会按规则析构，因此资源清理不依赖手工补写多条释放路径。</div><div class="notion-text notion-block-9303972c4f834239b526d84985d65847"><code class="notion-inline-code">std::ofstream</code> 离开作用域时会自动关闭文件。锁、文件、容器、智能指针和线程封装都可以使用同样的资源管理思路。</div><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-c43d8b8400e545378387b728ade222db" data-id="c43d8b8400e545378387b728ade222db"><span><div id="c43d8b8400e545378387b728ade222db" class="notion-header-anchor"></div><a class="notion-hash-link" href="#c43d8b8400e545378387b728ade222db" title="6. 类、对象与多态"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">6. 类、对象与多态</span></span></h3><div class="notion-text notion-block-01f6a7c25da449f2a5553b0e8d6cb43b">本章从「类的职责」「构造函数与成员初始化列表」和「析构函数」等方面说明类、对象与多态。</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-a73d1b97c5304faebf0479f8c655c221" data-id="a73d1b97c5304faebf0479f8c655c221"><span><div id="a73d1b97c5304faebf0479f8c655c221" class="notion-header-anchor"></div><a class="notion-hash-link" href="#a73d1b97c5304faebf0479f8c655c221" title="6.1 类的职责"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">6.1 类的职责</span></span></h4><div class="notion-text notion-block-7c359dadc4c24e8796cd14196337967d">类把数据、约束和操作组织在一起。字段保存对象状态，成员函数维护状态变化，访问控制负责保护类的不变量。</div><div class="notion-text notion-block-819f95f903ff449ea4069c8226db7e92">构造函数建立合法初始状态，<code class="notion-inline-code">TakeDamage</code> 保证生命值不会小于零。外部代码不能绕过接口随意破坏对象状态。</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-602a58e59355496087f216e8df3064a9" data-id="602a58e59355496087f216e8df3064a9"><span><div id="602a58e59355496087f216e8df3064a9" class="notion-header-anchor"></div><a class="notion-hash-link" href="#602a58e59355496087f216e8df3064a9" title="6.2 构造函数与成员初始化列表"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">6.2 构造函数与成员初始化列表</span></span></h4><div class="notion-text notion-block-5deae03f67d14793bb82534abb53f498">成员初始化列表在进入构造函数体前直接初始化成员：</div><div class="notion-text notion-block-c1294cf29e984149b420465a5a85b43e">成员的实际初始化顺序由它们在类中的声明顺序决定，与初始化列表中的书写顺序无关。初始化列表应尽量保持与成员声明一致，避免阅读误导和编译器警告。</div><div class="notion-text notion-block-e4774ef4e58a4d789c0765b18afe379a"><code class="notion-inline-code">explicit</code> 可以阻止单参数构造函数参与不期望的隐式转换：</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-dbb0a7cd39104d0fa75b130ad661cf6b" data-id="dbb0a7cd39104d0fa75b130ad661cf6b"><span><div id="dbb0a7cd39104d0fa75b130ad661cf6b" class="notion-header-anchor"></div><a class="notion-hash-link" href="#dbb0a7cd39104d0fa75b130ad661cf6b" title="6.3 析构函数"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">6.3 析构函数</span></span></h4><div class="notion-text notion-block-e2a8222b25344960a068d9212189c3e2">析构函数在对象生命周期结束时执行，用于释放对象直接拥有的资源：</div><div class="notion-text notion-block-25e45f24494d4acb970612ae871760d5">手工管理裸资源会同时引出拷贝、赋值、异常安全和所有权问题。实际项目更适合使用 <code class="notion-inline-code">std::vector&lt;int&gt;</code> 或 <code class="notion-inline-code">std::unique_ptr&lt;int[]&gt;</code>，让标准库对象负责资源释放。</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-ff7c24c7653c4dc3874d3ff777936c84" data-id="ff7c24c7653c4dc3874d3ff777936c84"><span><div id="ff7c24c7653c4dc3874d3ff777936c84" class="notion-header-anchor"></div><a class="notion-hash-link" href="#ff7c24c7653c4dc3874d3ff777936c84" title="6.4 this、静态成员与友元"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">6.4 <code class="notion-inline-code">this</code>、静态成员与友元</span></span></h4><div class="notion-text notion-block-181c753c7c7540f9b45965290ce52edd"><code class="notion-inline-code">this</code> 指向当前对象：</div><div class="notion-text notion-block-225a528b7ff4442f845e3081a865dbf4">静态成员属于类，而不是某个对象：</div><div class="notion-text notion-block-235caf26d6d04cc5952138103af83b57">友元可以访问类的非公有成员，但会扩大耦合范围。只有运算符重载、紧密协作类型或明确的底层接口确实需要时才使用。</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-107ff8dd10b2451482b7615e1441411b" data-id="107ff8dd10b2451482b7615e1441411b"><span><div id="107ff8dd10b2451482b7615e1441411b" class="notion-header-anchor"></div><a class="notion-hash-link" href="#107ff8dd10b2451482b7615e1441411b" title="6.5 继承与运行时多态"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">6.5 继承与运行时多态</span></span></h4><div class="notion-text notion-block-64fe10ee6af6477ab217eef314528245">继承表达“派生类属于基类的一种”，运行时多态通过虚函数完成：</div><div class="notion-text notion-block-70de6d8deb454dbf89b0eadc68be41f5"><code class="notion-inline-code">override</code> 要求编译器检查派生类函数是否真正覆盖基类虚函数，可防止参数或 <code class="notion-inline-code">const</code> 不一致造成的隐藏错误。</div><h5 class="notion-h notion-h4 notion-h-indent-2 notion-block-65acd66b304c49a0bce86a63fa55334b" data-id="65acd66b304c49a0bce86a63fa55334b"><span><div id="65acd66b304c49a0bce86a63fa55334b" class="notion-header-anchor"></div><a class="notion-hash-link" href="#65acd66b304c49a0bce86a63fa55334b" title="6.5.1 虚析构函数"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">6.5.1 虚析构函数</span></span></h5><div class="notion-text notion-block-7ccd4a22d3a14d3b89ae04ab3e44d294">当对象可能通过基类指针删除时，基类析构函数必须为虚函数：</div><div class="notion-text notion-block-6f3a470789aa427e9cb72f35e8bea564">如果基类析构函数不是虚函数，通过基类指针销毁派生对象会导致未定义行为。</div><h5 class="notion-h notion-h4 notion-h-indent-2 notion-block-bfd05b8e284b412094f0eddd649f8874" data-id="bfd05b8e284b412094f0eddd649f8874"><span><div id="bfd05b8e284b412094f0eddd649f8874" class="notion-header-anchor"></div><a class="notion-hash-link" href="#bfd05b8e284b412094f0eddd649f8874" title="6.5.2 对象切片"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">6.5.2 对象切片</span></span></h5><div class="notion-text notion-block-0f5a40d92906402a8fd026a6740e365e">派生对象按值赋给基类对象时，派生部分会被截断：</div><div class="notion-text notion-block-1a226f3c4f4b407d9aa74d670cf8a563">需要保留动态类型时，应通过引用、指针或智能指针使用多态对象。</div><h5 class="notion-h notion-h4 notion-h-indent-2 notion-block-bdd9d949a20e4e9dba7e04cd80e2bdc2" data-id="bdd9d949a20e4e9dba7e04cd80e2bdc2"><span><div id="bdd9d949a20e4e9dba7e04cd80e2bdc2" class="notion-header-anchor"></div><a class="notion-hash-link" href="#bdd9d949a20e4e9dba7e04cd80e2bdc2" title="6.5.3 组合与继承"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">6.5.3 组合与继承</span></span></h5><ul class="notion-list notion-list-disc notion-block-ddbf2b25bdd24e519b367e7a1c9cf254"><li>继承适合稳定的“是一个”关系，并要求派生类能够满足基类接口约束。</li></ul><ul class="notion-list notion-list-disc notion-block-6befe10d94654e6ab0b66074bc389f75"><li>组合适合“拥有一个”或“使用一个”关系，依赖更容易替换。</li></ul><div class="notion-text notion-block-1a4403a128e44f5aa348cd464fd14abf">游戏角色由移动、生命、技能和背包等能力组成时，组件组合通常比多层继承更灵活。</div><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-3488262cfdc245db9bd355f1d30236b7" data-id="3488262cfdc245db9bd355f1d30236b7"><span><div id="3488262cfdc245db9bd355f1d30236b7" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3488262cfdc245db9bd355f1d30236b7" title="7. 拷贝、移动"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">7. 拷贝、移动</span></span></h3><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-f0c5364a8e3e45e0a7125eae8c19d4ac" data-id="f0c5364a8e3e45e0a7125eae8c19d4ac"><span><div id="f0c5364a8e3e45e0a7125eae8c19d4ac" class="notion-header-anchor"></div><a class="notion-hash-link" href="#f0c5364a8e3e45e0a7125eae8c19d4ac" title="7.1 浅拷贝与深拷贝"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">7.1 浅拷贝与深拷贝</span></span></h4><div class="notion-text notion-block-6f17c5054cac48d28f88e6af602e3709">编译器生成的成员逐一拷贝对值类型成员通常足够。类直接拥有裸指针资源时，默认拷贝只会复制地址，多个对象可能指向同一块资源：</div><div class="notion-text notion-block-42d49c3016604101b4e77a4c69da7757">如果两个 <code class="notion-inline-code">Buffer</code> 对象复制后都在析构时释放 <code class="notion-inline-code">data</code>，会发生重复释放。深拷贝需要为新对象重新分配资源并复制内容。</div><div class="notion-text notion-block-fffd6b53f8f04db586754bf26a82ada8">实际项目优先使用能够正确复制或禁止复制的标准库成员：</div><div class="notion-text notion-block-27cb4e924d824a4eb29405e16cd79629">此时编译器生成的拷贝、移动和析构行为已经符合资源语义。</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-e630121206db434faa9ea2f071fa1449" data-id="e630121206db434faa9ea2f071fa1449"><span><div id="e630121206db434faa9ea2f071fa1449" class="notion-header-anchor"></div><a class="notion-hash-link" href="#e630121206db434faa9ea2f071fa1449" title="7.2 零法则、三法则与五法则"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">7.2 零法则、三法则与五法则</span></span></h4><div class="notion-text notion-block-f4490fcd548c4811a399e2af221db105">本节从「零法则」「三法则」和「五法则」等方面说明零法则、三法则与五法则。</div><h5 class="notion-h notion-h4 notion-h-indent-2 notion-block-09430e0404dd4b9991acf5a667a4485c" data-id="09430e0404dd4b9991acf5a667a4485c"><span><div id="09430e0404dd4b9991acf5a667a4485c" class="notion-header-anchor"></div><a class="notion-hash-link" href="#09430e0404dd4b9991acf5a667a4485c" title="7.2.1 零法则"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">7.2.1 零法则</span></span></h5><div class="notion-text notion-block-686970e50617491f87f91f2503305f2c">类只使用标准库容器、字符串和智能指针管理资源时，通常不需要手写析构、拷贝或移动函数。零法则应作为默认选择。</div><h5 class="notion-h notion-h4 notion-h-indent-2 notion-block-755d1bee34e74320bacfb85338601f0c" data-id="755d1bee34e74320bacfb85338601f0c"><span><div id="755d1bee34e74320bacfb85338601f0c" class="notion-header-anchor"></div><a class="notion-hash-link" href="#755d1bee34e74320bacfb85338601f0c" title="7.2.2 三法则"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">7.2.2 三法则</span></span></h5><div class="notion-text notion-block-08b6d34284354f0eaca558f8895fc5a7">类需要自定义以下任意一个函数时，通常需要同时检查另外两个：</div><ol start="1" class="notion-list notion-list-numbered notion-block-e8727ab949994a3b81a1619db4b65cb1" style="list-style-type:decimal"><li>析构函数；</li></ol><ol start="2" class="notion-list notion-list-numbered notion-block-6c7fea96f5d3491c8c60e3ec7d6b3d4a" style="list-style-type:decimal"><li>拷贝构造函数；</li></ol><ol start="3" class="notion-list notion-list-numbered notion-block-8aa60cd19e67453d95dcc88f3bb31f47" style="list-style-type:decimal"><li>拷贝赋值运算符。</li></ol><h5 class="notion-h notion-h4 notion-h-indent-2 notion-block-77c1cfe3455342b4b912e6f7e2a3c933" data-id="77c1cfe3455342b4b912e6f7e2a3c933"><span><div id="77c1cfe3455342b4b912e6f7e2a3c933" class="notion-header-anchor"></div><a class="notion-hash-link" href="#77c1cfe3455342b4b912e6f7e2a3c933" title="7.2.3 五法则"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">7.2.3 五法则</span></span></h5><div class="notion-text notion-block-2faaf614821a436d9ed5e848878c8d1f">C++11 增加移动语义后，还需要检查：</div><ol start="1" class="notion-list notion-list-numbered notion-block-0930a522d1084a75a0d6494fa3b0ecf4" style="list-style-type:decimal"><li>移动构造函数；</li></ol><ol start="2" class="notion-list notion-list-numbered notion-block-cd4cfe6e897e434b8a120ddf6c7eeee7" style="list-style-type:decimal"><li>移动赋值运算符。</li></ol><div class="notion-text notion-block-a3487b55b8a844d0962dfeca35893459">五法则描述的是资源类需要保持的一组一致语义，不代表所有类都应手写五个函数。</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-b7148c13f25246bd8c977e156f724e52" data-id="b7148c13f25246bd8c977e156f724e52"><span><div id="b7148c13f25246bd8c977e156f724e52" class="notion-header-anchor"></div><a class="notion-hash-link" href="#b7148c13f25246bd8c977e156f724e52" title="7.3 左值、右值与引用折叠"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">7.3 左值、右值与引用折叠</span></span></h4><div class="notion-text notion-block-f48beb68aff64b4dbc3502b0755cd194">左值通常表示具有稳定身份、可以取得地址的表达式；右值通常表示临时值或即将被消费的对象。</div><div class="notion-text notion-block-106a7bd04deb425b9edb1671a4513ead">常见引用形式：</div><ul class="notion-list notion-list-disc notion-block-d46296bfcba142ef952c094423d92372"><li><code class="notion-inline-code">T&amp;</code>：左值引用；</li></ul><ul class="notion-list notion-list-disc notion-block-3027484c58644e0696d57d1fb08dd3f0"><li><code class="notion-inline-code">const T&amp;</code>：可绑定左值和右值，常用于只读参数；</li></ul><ul class="notion-list notion-list-disc notion-block-f2a31efe90554569adb46c27539369d9"><li><code class="notion-inline-code">T&amp;&amp;</code>：右值引用，用于移动语义和完美转发。</li></ul><div class="notion-text notion-block-835cce08259e49f4a18165e0fcc501f7">命名后的右值引用变量本身是左值：</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-c1fb4bd49da84aa29911f4b74cdc8d84" data-id="c1fb4bd49da84aa29911f4b74cdc8d84"><span><div id="c1fb4bd49da84aa29911f4b74cdc8d84" class="notion-header-anchor"></div><a class="notion-hash-link" href="#c1fb4bd49da84aa29911f4b74cdc8d84" title="7.4 std::move"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">7.4 <code class="notion-inline-code">std::move</code></span></span></h4><div class="notion-text notion-block-2cd0ddd6b7ee473db02f175d1ec8b8e0"><code class="notion-inline-code">std::move</code> 不执行资源移动，它把表达式转换为可供移动操作接收的值类别：</div><div class="notion-text notion-block-806c0febebf445b4a2b8eaefa14ca5c0"><code class="notion-inline-code">target</code> 的构造函数可以接管 <code class="notion-inline-code">source</code> 的内部资源。移动后的标准库对象仍处于有效但通常未指定的状态，可以析构、重新赋值或调用明确允许的操作，但不应假设原内容仍然存在。</div><div class="notion-text notion-block-130916cc2ad94f639150efa2ba4e77b7">移动仅在目标类型提供移动操作时发生。对 <code class="notion-inline-code">const</code> 对象调用 <code class="notion-inline-code">std::move</code> 通常仍会选择拷贝，因为移动构造函数一般需要修改源对象。</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-e42914f36ed94887b149eee1dc9b74bb" data-id="e42914f36ed94887b149eee1dc9b74bb"><span><div id="e42914f36ed94887b149eee1dc9b74bb" class="notion-header-anchor"></div><a class="notion-hash-link" href="#e42914f36ed94887b149eee1dc9b74bb" title="7.5 移动构造与移动赋值"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">7.5 移动构造与移动赋值</span></span></h4><div class="notion-text notion-block-c67bb213eea442ebb9b02d35da668390">资源类的移动操作通常接管资源，并把源对象置于可安全析构的状态：</div><div class="notion-text notion-block-f613b3426dbf43d988a416b2e2798392">实际项目仍应优先用标准库类型消除手工资源管理。该示例用于说明移动操作需要维护源对象和目标对象的生命周期安全。</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-2f85a2be2eee4d3daaa43f74b1f5276b" data-id="2f85a2be2eee4d3daaa43f74b1f5276b"><span><div id="2f85a2be2eee4d3daaa43f74b1f5276b" class="notion-header-anchor"></div><a class="notion-hash-link" href="#2f85a2be2eee4d3daaa43f74b1f5276b" title="7.6 拷贝消除"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">7.6 拷贝消除</span></span></h4><div class="notion-text notion-block-89770c9c32a34f4e99e7bca812003fa9">编译器可以在部分返回值和临时对象场景中省略拷贝或移动。C++17 对若干纯右值初始化场景规定了保证拷贝消除：</div><div class="notion-text notion-block-1421aedda7e34cd8a53b22e98e887137">按值返回局部对象通常比返回裸指针更安全，也不应为了“避免拷贝”而习惯性返回动态分配对象。</div><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-bde50e920a1e4257bfa480d75c51dbea" data-id="bde50e920a1e4257bfa480d75c51dbea"><span><div id="bde50e920a1e4257bfa480d75c51dbea" class="notion-header-anchor"></div><a class="notion-hash-link" href="#bde50e920a1e4257bfa480d75c51dbea" title="8. 运算符重载与类型转换"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">8. 运算符重载与类型转换</span></span></h3><div class="notion-text notion-block-adbb6a9e23fb478daec70484d83beb50">本章从「运算符重载」「四种命名类型转换」和「隐式转换与 explicit」等方面说明运算符重载与类型转换。</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-964a8776a5364429862ce49b4b1ad62d" data-id="964a8776a5364429862ce49b4b1ad62d"><span><div id="964a8776a5364429862ce49b4b1ad62d" class="notion-header-anchor"></div><a class="notion-hash-link" href="#964a8776a5364429862ce49b4b1ad62d" title="8.1 运算符重载"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">8.1 运算符重载</span></span></h4><div class="notion-text notion-block-71579f829d4a4a878287876d254aa4cd">运算符重载用于让自定义类型遵循已有运算符的语义：</div><div class="notion-text notion-block-4adf89a4e9944dbf96f8c07a015cca14">重载原则：</div><ul class="notion-list notion-list-disc notion-block-a5752a8b737a40d8a3f60617ac6344ec"><li>保持运算符的常见含义；</li></ul><ul class="notion-list notion-list-disc notion-block-ebbef6aec515426ea5486a4b47ddb506"><li>不通过运算符隐藏昂贵或意外的副作用；</li></ul><ul class="notion-list notion-list-disc notion-block-14e1a2efc980415f96b104821df762a5"><li>对称二元运算符通常实现为非成员函数；</li></ul><ul class="notion-list notion-list-disc notion-block-de0567ada8394c8db085c3e5564c515c"><li>赋值、下标、调用和成员访问等运算符必须按语言规则实现为成员函数；</li></ul><ul class="notion-list notion-list-disc notion-block-f7e908ea331344ada6f3482d7cc1d72c"><li>返回类型和参数形式应支持自然的组合使用。</li></ul><div class="notion-text notion-block-769ee3c9e86345cbba05d9c4832bf5f9">复合赋值通常先实现，再复用到普通二元运算：</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-47fcb33329dc41909ca252514411d7ba" data-id="47fcb33329dc41909ca252514411d7ba"><span><div id="47fcb33329dc41909ca252514411d7ba" class="notion-header-anchor"></div><a class="notion-hash-link" href="#47fcb33329dc41909ca252514411d7ba" title="8.2 四种命名类型转换"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">8.2 四种命名类型转换</span></span></h4><div class="notion-text notion-block-e0926cf3ad124767bc29e228710bb218">本节从「static_cast」「dynamic_cast」和「const_cast」等方面说明四种命名类型转换。</div><h5 class="notion-h notion-h4 notion-h-indent-2 notion-block-cc5f654b537d466881176c5cff60036d" data-id="cc5f654b537d466881176c5cff60036d"><span><div id="cc5f654b537d466881176c5cff60036d" class="notion-header-anchor"></div><a class="notion-hash-link" href="#cc5f654b537d466881176c5cff60036d" title="8.2.1 static_cast"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">8.2.1 <code class="notion-inline-code">static_cast</code></span></span></h5><div class="notion-text notion-block-a58334d19d4244eca1de42d59f628c48">用于具有明确语言关系的转换，例如数值转换、枚举转换和继承层次中的受控转换：</div><div class="notion-text notion-block-1f9ac9f16a0646349814078249c1a8df">数值窄化可能丢失信息，<code class="notion-inline-code">static_cast</code> 只让转换意图更明确，不会自动保证安全。</div><h5 class="notion-h notion-h4 notion-h-indent-2 notion-block-8457a9f76b4d4115aaac2158e8a78f19" data-id="8457a9f76b4d4115aaac2158e8a78f19"><span><div id="8457a9f76b4d4115aaac2158e8a78f19" class="notion-header-anchor"></div><a class="notion-hash-link" href="#8457a9f76b4d4115aaac2158e8a78f19" title="8.2.2 dynamic_cast"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">8.2.2 <code class="notion-inline-code">dynamic_cast</code></span></span></h5><div class="notion-text notion-block-447e1eb0cd634d19bef1e105544a573e">用于多态继承体系中的运行时类型检查：</div><div class="notion-text notion-block-b5ea6eef4fd7408e9f1cd29a332f11e6">指针转换失败返回 <code class="notion-inline-code">nullptr</code>；引用转换失败抛出 <code class="notion-inline-code">std::bad_cast</code>。向下转换要求基类具有多态能力，通常至少包含一个虚函数。</div><h5 class="notion-h notion-h4 notion-h-indent-2 notion-block-f255a39290bf4affb87270ca197b45c4" data-id="f255a39290bf4affb87270ca197b45c4"><span><div id="f255a39290bf4affb87270ca197b45c4" class="notion-header-anchor"></div><a class="notion-hash-link" href="#f255a39290bf4affb87270ca197b45c4" title="8.2.3 const_cast"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">8.2.3 <code class="notion-inline-code">const_cast</code></span></span></h5><div class="notion-text notion-block-bd40ad02342b4a3d8d408fab98e2ad47">用于增加或移除 <code class="notion-inline-code">const</code>、<code class="notion-inline-code">volatile</code> 限定：</div><div class="notion-text notion-block-9176b6a2e4704106a234ec331f7e8123">如果原对象本身确实是常量，随后通过移除限定的指针修改它会导致未定义行为。<code class="notion-inline-code">const_cast</code> 主要用于兼容设计不合理的旧接口，不应作为常规修改手段。</div><h5 class="notion-h notion-h4 notion-h-indent-2 notion-block-8e16ee559ec849faae5c2764ccd44b99" data-id="8e16ee559ec849faae5c2764ccd44b99"><span><div id="8e16ee559ec849faae5c2764ccd44b99" class="notion-header-anchor"></div><a class="notion-hash-link" href="#8e16ee559ec849faae5c2764ccd44b99" title="8.2.4 reinterpret_cast"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">8.2.4 <code class="notion-inline-code">reinterpret_cast</code></span></span></h5><div class="notion-text notion-block-226b42081d57485f9a7ec6559925a02c">用于底层地址或表示形式相关转换：</div><div class="notion-text notion-block-8a671bad1b764f33b4a62ce1d092032b">这种转换绕过大部分类型系统保护，只适合硬件接口、序列化底层实现和平台相关代码。转换成功不代表目标访问一定满足对齐、别名和生命周期规则。</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-19a697cff8ac4d4da49c5dffbdc90a17" data-id="19a697cff8ac4d4da49c5dffbdc90a17"><span><div id="19a697cff8ac4d4da49c5dffbdc90a17" class="notion-header-anchor"></div><a class="notion-hash-link" href="#19a697cff8ac4d4da49c5dffbdc90a17" title="8.3 隐式转换与 explicit"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">8.3 隐式转换与 <code class="notion-inline-code">explicit</code></span></span></h4><div class="notion-text notion-block-b1b951999f58465f88fa8f8bd6e2be88">单参数构造函数和转换运算符可能参与隐式转换：</div><div class="notion-text notion-block-a6bf0be0484c4eeba597f341b43b4a63"><code class="notion-inline-code">explicit</code> 要求调用者明确表达转换意图：</div><div class="notion-text notion-block-2cd9ffb268454923a3811023d20bab24">接口边界上的隐式转换越多，重载决议和错误定位越困难。自定义数值包装、ID 类型和资源句柄通常适合使用 <code class="notion-inline-code">explicit</code>。</div><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-b446a3ea06fd4d20b9d9508272911ee9" data-id="b446a3ea06fd4d20b9d9508272911ee9"><span><div id="b446a3ea06fd4d20b9d9508272911ee9" class="notion-header-anchor"></div><a class="notion-hash-link" href="#b446a3ea06fd4d20b9d9508272911ee9" title="9. 模板与泛型编程"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">9. 模板与泛型编程</span></span></h3><div class="notion-text notion-block-5352fc885b4946bbbddfe8f5c4e3d483">本章从「函数模板」「类模板」和「特化与重载」等方面说明模板与泛型编程。</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-6f576d777cd341cd93b2dade636a920e" data-id="6f576d777cd341cd93b2dade636a920e"><span><div id="6f576d777cd341cd93b2dade636a920e" class="notion-header-anchor"></div><a class="notion-hash-link" href="#6f576d777cd341cd93b2dade636a920e" title="9.1 函数模板"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">9.1 函数模板</span></span></h4><div class="notion-text notion-block-ec029c16dfa54965aec5fa10a6e04a09">函数模板描述一组适用于不同类型的通用操作：</div><div class="notion-text notion-block-d51d28314f3f4cbfb2e8944f2f580f1c">编译器根据调用参数实例化具体函数：</div><div class="notion-text notion-block-877443596ec34a679d01d19969756c9c">模板能够编译不代表所有类型都满足语义要求。上面的 <code class="notion-inline-code">Max</code> 要求类型支持 <code class="notion-inline-code">&lt;</code> 比较，并且返回引用的对象生命周期必须覆盖调用结果的使用范围。</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-21cf59b3bbf74a1aabc6fcdee5610e3d" data-id="21cf59b3bbf74a1aabc6fcdee5610e3d"><span><div id="21cf59b3bbf74a1aabc6fcdee5610e3d" class="notion-header-anchor"></div><a class="notion-hash-link" href="#21cf59b3bbf74a1aabc6fcdee5610e3d" title="9.2 类模板"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">9.2 类模板</span></span></h4><div class="notion-text notion-block-5bf766f7fee24e64baef650d43a57e8a">使用方式：</div><div class="notion-text notion-block-e9fc7e1cee1a444f96ae6197bba145f3">模板定义通常放在头文件中，因为实例化发生在使用位置。只有显式实例化等特殊方案能够把部分模板实现移到源文件。</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-4892bedf2efa41b1850bc6008b8c1d1b" data-id="4892bedf2efa41b1850bc6008b8c1d1b"><span><div id="4892bedf2efa41b1850bc6008b8c1d1b" class="notion-header-anchor"></div><a class="notion-hash-link" href="#4892bedf2efa41b1850bc6008b8c1d1b" title="9.3 特化与重载"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">9.3 特化与重载</span></span></h4><div class="notion-text notion-block-11a027e8aa5d4b2d9c4229606e3ee412">当通用模板不适合某类类型时，可以使用：</div><ul class="notion-list notion-list-disc notion-block-9bcbb2fb3b9d401baca5441287a621e4"><li>函数重载；</li></ul><ul class="notion-list notion-list-disc notion-block-aa6e34e2de254d148e778276d39d53d6"><li>类模板偏特化；</li></ul><ul class="notion-list notion-list-disc notion-block-aed11f8c23184240bd873fba91fc59b3"><li>类模板全特化；</li></ul><ul class="notion-list notion-list-disc notion-block-13cab392a5184410b97a08a1ca35784b"><li><code class="notion-inline-code">if constexpr</code>；</li></ul><ul class="notion-list notion-list-disc notion-block-b86177d4a366443aa79e822b0c588d56"><li>C++20 Concepts 和 <code class="notion-inline-code">requires</code>。</li></ul><div class="notion-text notion-block-6b715931f77d4b1db0f363ca16eeae3d">函数模板通常优先通过重载表达特殊行为，类模板才使用偏特化组织不同类型族。</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-427f9d681a6e4507a773ca3e34f04240" data-id="427f9d681a6e4507a773ca3e34f04240"><span><div id="427f9d681a6e4507a773ca3e34f04240" class="notion-header-anchor"></div><a class="notion-hash-link" href="#427f9d681a6e4507a773ca3e34f04240" title="9.4 if constexpr"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">9.4 <code class="notion-inline-code">if constexpr</code></span></span></h4><div class="notion-text notion-block-c69df97070c947a3a6b26cf57349c844">C++17 的 <code class="notion-inline-code">if constexpr</code> 可以根据编译期条件选择分支：</div><div class="notion-text notion-block-9999e3c09e134c9c84fe3f05eb4e042a">未选中的分支不会参与当前模板实例的完整语义检查，因此适合处理不同类型类别的编译期分支。</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-9b687c6aebcd42ea81a678c75d90dd4e" data-id="9b687c6aebcd42ea81a678c75d90dd4e"><span><div id="9b687c6aebcd42ea81a678c75d90dd4e" class="notion-header-anchor"></div><a class="notion-hash-link" href="#9b687c6aebcd42ea81a678c75d90dd4e" title="9.5 泛型代码的约束"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">9.5 泛型代码的约束</span></span></h4><div class="notion-text notion-block-a5d3d4ebffa1414cbb0668fc4bca4a29">泛型函数应说明类型必须满足的操作和语义。C++20 可以使用 Concept 表达约束：</div><div class="notion-text notion-block-c0cf768877e24a528c89737a7b4bb806">没有使用 Concept 时，也应通过清晰命名、静态断言和文档说明模板要求，避免把复杂错误推迟到深层实例化信息中。</div><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-8da76bd2e7e5489fbca05ec6a39f3fc9" data-id="8da76bd2e7e5489fbca05ec6a39f3fc9"><span><div id="8da76bd2e7e5489fbca05ec6a39f3fc9" class="notion-header-anchor"></div><a class="notion-hash-link" href="#8da76bd2e7e5489fbca05ec6a39f3fc9" title="10. STL 容器、迭代器与算法"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">10. STL 容器、迭代器与算法</span></span></h3><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-6b9f3944d00b4d009f7ad595a4e6e750" data-id="6b9f3944d00b4d009f7ad595a4e6e750"><span><div id="6b9f3944d00b4d009f7ad595a4e6e750" class="notion-header-anchor"></div><a class="notion-hash-link" href="#6b9f3944d00b4d009f7ad595a4e6e750" title="10.1 STL 的组成"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">10.1 STL 的组成</span></span></h4><div class="notion-text notion-block-d50fbe3d3f8b48bd9fd7198ff930374e">标准模板库的核心部分包括：</div><ol start="1" class="notion-list notion-list-numbered notion-block-dafea8f21aa54e9183f57b2cfdeeef7b" style="list-style-type:decimal"><li><b>容器：</b>保存数据，例如 <code class="notion-inline-code">vector</code>、<code class="notion-inline-code">list</code>、<code class="notion-inline-code">map</code>。</li></ol><ol start="2" class="notion-list notion-list-numbered notion-block-943ed7eabf1c4a19a2d58e8b2be0f0be" style="list-style-type:decimal"><li><b>迭代器：</b>描述访问范围的位置和遍历能力。</li></ol><ol start="3" class="notion-list notion-list-numbered notion-block-85a16e59a9e348e9a15e51f77eb2e266" style="list-style-type:decimal"><li><b>算法：</b>对迭代器范围执行查找、排序、变换等操作。</li></ol><ol start="4" class="notion-list notion-list-numbered notion-block-8120db531eed443fb2d3f5b95331085d" style="list-style-type:decimal"><li><b>函数对象与 Lambda：</b>为算法提供比较、筛选和转换规则。</li></ol><ol start="5" class="notion-list notion-list-numbered notion-block-cb3394c1a979488a8b8a06e2af40961e" style="list-style-type:decimal"><li><b>容器适配器：</b>在已有容器上提供栈、队列和优先队列接口。</li></ol><div class="notion-text notion-block-bc67ee8d37644f6da9171d22c17ff337">典型调用形式：</div><div class="notion-text notion-block-73050002693840c29a37ec93aef47a9b">算法不直接依赖某个具体容器，而是依赖迭代器能力。<code class="notion-inline-code">std::sort</code> 需要随机访问迭代器，因此可用于 <code class="notion-inline-code">vector</code> 和 <code class="notion-inline-code">deque</code>，不能直接用于 <code class="notion-inline-code">list</code>；<code class="notion-inline-code">list</code> 提供自己的成员函数 <code class="notion-inline-code">sort()</code>。</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-a9c3594ef942412bb3a23ff3ce879171" data-id="a9c3594ef942412bb3a23ff3ce879171"><span><div id="a9c3594ef942412bb3a23ff3ce879171" class="notion-header-anchor"></div><a class="notion-hash-link" href="#a9c3594ef942412bb3a23ff3ce879171" title="10.2 顺序容器"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">10.2 顺序容器</span></span></h4><table class="notion-simple-table notion-block-b4d2f784da0140d0abf2bbc54034e3ee"><tbody><tr class="notion-simple-table-row notion-simple-table-header-row notion-block-374cadfab11048bf841658c7d06e0e0a"><td class="" style="width:120px"><div class="notion-simple-table-cell">容器</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">主要特点</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">典型操作复杂度</div></td></tr><tr class="notion-simple-table-row notion-block-c3d63206f6dc4b78b7ce5e74468e084f"><td class="" style="width:120px"><div class="notion-simple-table-cell"><code class="notion-inline-code">vector</code></div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">连续内存，缓存局部性好，支持随机访问</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">下标 <code class="notion-inline-code">O(1)</code>；尾部追加均摊 <code class="notion-inline-code">O(1)</code>；中间插删 <code class="notion-inline-code">O(n)</code></div></td></tr><tr class="notion-simple-table-row notion-block-0935e342ead04d71a7022c332dbc59f0"><td class="" style="width:120px"><div class="notion-simple-table-cell"><code class="notion-inline-code">deque</code></div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">分段连续，支持随机访问和两端操作</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">随机访问 <code class="notion-inline-code">O(1)</code>；两端插删通常 <code class="notion-inline-code">O(1)</code></div></td></tr><tr class="notion-simple-table-row notion-block-18d28ac986284e49a22f2683d16c7388"><td class="" style="width:120px"><div class="notion-simple-table-cell"><code class="notion-inline-code">list</code></div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">双向链表，不支持随机访问</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">已知位置插删 <code class="notion-inline-code">O(1)</code>；查找位置 <code class="notion-inline-code">O(n)</code></div></td></tr><tr class="notion-simple-table-row notion-block-d2814a6d2cb648dfbfc8281e8efbffe4"><td class="" style="width:120px"><div class="notion-simple-table-cell"><code class="notion-inline-code">array</code></div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">固定长度，元素直接存储在对象内部</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">随机访问 <code class="notion-inline-code">O(1)</code></div></td></tr></tbody></table><div class="notion-text notion-block-f27c970d2f804d419ee6681a0891120d">多数需要动态数组的场景优先使用 <code class="notion-inline-code">vector</code>。只有频繁在两端插删或确实需要稳定节点地址时，再考虑 <code class="notion-inline-code">deque</code>、<code class="notion-inline-code">list</code> 等其他容器。</div><h5 class="notion-h notion-h4 notion-h-indent-2 notion-block-21acc46ebc584319838b4f01f0fdb114" data-id="21acc46ebc584319838b4f01f0fdb114"><span><div id="21acc46ebc584319838b4f01f0fdb114" class="notion-header-anchor"></div><a class="notion-hash-link" href="#21acc46ebc584319838b4f01f0fdb114" title="10.2.1 vector 的容量"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">10.2.1 <code class="notion-inline-code">vector</code> 的容量</span></span></h5><div class="notion-text notion-block-c65fd70ab7b1434691171946579dca9a"><code class="notion-inline-code">reserve</code> 只调整容量，不改变 <code class="notion-inline-code">size</code>。<code class="notion-inline-code">resize</code> 会改变元素数量，并构造或销毁元素。</div><div class="notion-text notion-block-eec6d83946e54732a743e9e4d8f3382e">扩容需要申请新内存并移动或复制已有元素，因此单次 <code class="notion-inline-code">push_back</code> 可能为 <code class="notion-inline-code">O(n)</code>，连续追加的均摊复杂度为 <code class="notion-inline-code">O(1)</code>。</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-9616e85f72ba4eafac3aaa33f7aa2888" data-id="9616e85f72ba4eafac3aaa33f7aa2888"><span><div id="9616e85f72ba4eafac3aaa33f7aa2888" class="notion-header-anchor"></div><a class="notion-hash-link" href="#9616e85f72ba4eafac3aaa33f7aa2888" title="10.3 关联容器"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">10.3 关联容器</span></span></h4><div class="notion-text notion-block-fbfdaf63868a4d8bbd0b373624398bfd">本节从「有序关联容器」和「无序关联容器」两方面说明关联容器。</div><h5 class="notion-h notion-h4 notion-h-indent-2 notion-block-ae16c1745403444b97b3088583f567e0" data-id="ae16c1745403444b97b3088583f567e0"><span><div id="ae16c1745403444b97b3088583f567e0" class="notion-header-anchor"></div><a class="notion-hash-link" href="#ae16c1745403444b97b3088583f567e0" title="10.3.1 有序关联容器"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">10.3.1 有序关联容器</span></span></h5><div class="notion-text notion-block-0663dad9c02d4ed9904e45af95fedc04"><code class="notion-inline-code">set</code>、<code class="notion-inline-code">map</code>、<code class="notion-inline-code">multiset</code> 和 <code class="notion-inline-code">multimap</code> 按比较规则维护顺序，常见实现基于平衡树：</div><div class="notion-text notion-block-288ec54a14ea4ae4bcc40973eeb731d9">查找、插入和删除通常为 <code class="notion-inline-code">O(log n)</code>，并支持有序遍历和范围查询。</div><h5 class="notion-h notion-h4 notion-h-indent-2 notion-block-dfb4507071f7462885f7622fd997d7c1" data-id="dfb4507071f7462885f7622fd997d7c1"><span><div id="dfb4507071f7462885f7622fd997d7c1" class="notion-header-anchor"></div><a class="notion-hash-link" href="#dfb4507071f7462885f7622fd997d7c1" title="10.3.2 无序关联容器"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">10.3.2 无序关联容器</span></span></h5><div class="notion-text notion-block-2d72a5e1764b485ca9aa546179ab61c7"><code class="notion-inline-code">unordered_set</code> 和 <code class="notion-inline-code">unordered_map</code> 基于哈希结构：</div><div class="notion-text notion-block-10c2924159f949d097cc07dbef27f783">查找、插入和删除的平均复杂度通常为 <code class="notion-inline-code">O(1)</code>；冲突严重时，最坏情况可能退化。哈希容器不维护键的排序关系。</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-bf45baab2eca4da1b1a6279607099252" data-id="bf45baab2eca4da1b1a6279607099252"><span><div id="bf45baab2eca4da1b1a6279607099252" class="notion-header-anchor"></div><a class="notion-hash-link" href="#bf45baab2eca4da1b1a6279607099252" title="10.4 容器适配器"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">10.4 容器适配器</span></span></h4><div class="notion-text notion-block-b24a1ae42ad84d8f9e22641186abc651">本节从「stack」「queue」和「priority_queue」等方面说明容器适配器。</div><h5 class="notion-h notion-h4 notion-h-indent-2 notion-block-a2aebebec9864768b40e85ed7888c79b" data-id="a2aebebec9864768b40e85ed7888c79b"><span><div id="a2aebebec9864768b40e85ed7888c79b" class="notion-header-anchor"></div><a class="notion-hash-link" href="#a2aebebec9864768b40e85ed7888c79b" title="10.4.1 stack"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">10.4.1 <code class="notion-inline-code">stack</code></span></span></h5><div class="notion-text notion-block-f94bbbe24fad465b9b6d1cec9aa0c9ea">后进先出：</div><h5 class="notion-h notion-h4 notion-h-indent-2 notion-block-f0e3258f38be455b9c6f72f9ba36580f" data-id="f0e3258f38be455b9c6f72f9ba36580f"><span><div id="f0e3258f38be455b9c6f72f9ba36580f" class="notion-header-anchor"></div><a class="notion-hash-link" href="#f0e3258f38be455b9c6f72f9ba36580f" title="10.4.2 queue"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">10.4.2 <code class="notion-inline-code">queue</code></span></span></h5><div class="notion-text notion-block-5e790638072845fc9509d417faed2211">先进先出：</div><h5 class="notion-h notion-h4 notion-h-indent-2 notion-block-9edd24ffdec94c50a4abb923bfa26804" data-id="9edd24ffdec94c50a4abb923bfa26804"><span><div id="9edd24ffdec94c50a4abb923bfa26804" class="notion-header-anchor"></div><a class="notion-hash-link" href="#9edd24ffdec94c50a4abb923bfa26804" title="10.4.3 priority_queue"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">10.4.3 <code class="notion-inline-code">priority_queue</code></span></span></h5><div class="notion-text notion-block-563382953048422f88213f6bf3f785fb">默认大顶堆，<code class="notion-inline-code">top()</code> 返回最大元素：</div><div class="notion-text notion-block-e6a6f9d1dd494fa18793acfd2f796368">小顶堆写法：</div><div class="notion-text notion-block-fb0c866edb5c47bc9e04bc5717d1908b"><code class="notion-inline-code">top</code> 为 <code class="notion-inline-code">O(1)</code>，<code class="notion-inline-code">push</code> 和 <code class="notion-inline-code">pop</code> 通常为 <code class="notion-inline-code">O(log n)</code>。</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-ded9020f088f458f9d72e04f93c28274" data-id="ded9020f088f458f9d72e04f93c28274"><span><div id="ded9020f088f458f9d72e04f93c28274" class="notion-header-anchor"></div><a class="notion-hash-link" href="#ded9020f088f458f9d72e04f93c28274" title="10.5 迭代器失效"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">10.5 迭代器失效</span></span></h4><div class="notion-text notion-block-71d33fd6a0d1495a9ba5549fd7bbb37a">容器修改可能使现有迭代器、指针和引用失效：</div><ul class="notion-list notion-list-disc notion-block-697c1f8bd02740d7bd10903e2477e780"><li><code class="notion-inline-code">vector</code> 重新分配容量时，指向元素的迭代器、指针和引用全部失效；</li></ul><ul class="notion-list notion-list-disc notion-block-5c653e85873e477b89f0d9dfbb83e8d4"><li><code class="notion-inline-code">vector</code> 在中间插入或删除时，操作位置及其后的迭代器通常失效；</li></ul><ul class="notion-list notion-list-disc notion-block-0c2a0e74156546bfb38391413dab5544"><li><code class="notion-inline-code">list</code> 插入通常不影响其他节点的迭代器，删除只使被删除节点失效；</li></ul><ul class="notion-list notion-list-disc notion-block-caeb6876eb724f799bc313126042b317"><li>无序容器发生重新哈希时，迭代器会失效。</li></ul><div class="notion-text notion-block-a8df68dc82644d14916fff35b446a5a2">删除遍历中的元素时，应使用容器返回的新迭代器：</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-7f634280d74442daa221bf2c1e037f9c" data-id="7f634280d74442daa221bf2c1e037f9c"><span><div id="7f634280d74442daa221bf2c1e037f9c" class="notion-header-anchor"></div><a class="notion-hash-link" href="#7f634280d74442daa221bf2c1e037f9c" title="10.6 常用算法"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">10.6 常用算法</span></span></h4><div class="notion-text notion-block-8035429e12f94adea10504c9426ceefd">本节从「查找与判断」「排序」和「变换」等方面说明常用算法。</div><h5 class="notion-h notion-h4 notion-h-indent-2 notion-block-d4973688f87c469a8dfd14a7c63d20ce" data-id="d4973688f87c469a8dfd14a7c63d20ce"><span><div id="d4973688f87c469a8dfd14a7c63d20ce" class="notion-header-anchor"></div><a class="notion-hash-link" href="#d4973688f87c469a8dfd14a7c63d20ce" title="10.6.1 查找与判断"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">10.6.1 查找与判断</span></span></h5><h5 class="notion-h notion-h4 notion-h-indent-2 notion-block-f1162bd593394775b58f9216260b47d4" data-id="f1162bd593394775b58f9216260b47d4"><span><div id="f1162bd593394775b58f9216260b47d4" class="notion-header-anchor"></div><a class="notion-hash-link" href="#f1162bd593394775b58f9216260b47d4" title="10.6.2 排序"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">10.6.2 排序</span></span></h5><div class="notion-text notion-block-7cda73b1aadd457490565e825623fbea">比较函数必须满足严格弱序关系。不要使用 <code class="notion-inline-code">&lt;=</code> 代替 <code class="notion-inline-code">&lt;</code>，否则排序算法的行为可能不符合要求。</div><h5 class="notion-h notion-h4 notion-h-indent-2 notion-block-db37b1deea654c689c0c305b469eb0cc" data-id="db37b1deea654c689c0c305b469eb0cc"><span><div id="db37b1deea654c689c0c305b469eb0cc" class="notion-header-anchor"></div><a class="notion-hash-link" href="#db37b1deea654c689c0c305b469eb0cc" title="10.6.3 变换"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">10.6.3 变换</span></span></h5><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-20f6a86ac7754bbba6aec4ae39b35374" data-id="20f6a86ac7754bbba6aec4ae39b35374"><span><div id="20f6a86ac7754bbba6aec4ae39b35374" class="notion-header-anchor"></div><a class="notion-hash-link" href="#20f6a86ac7754bbba6aec4ae39b35374" title="10.7 Lambda 表达式"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">10.7 Lambda 表达式</span></span></h4><div class="notion-text notion-block-b41b7e6f38d24d3cb2a97429877384d6">常见捕获形式：</div><ul class="notion-list notion-list-disc notion-block-1896abfa33144c8696d8363ba2fe6613"><li><code class="notion-inline-code">[value]</code>：按值捕获；</li></ul><ul class="notion-list notion-list-disc notion-block-d4fbdd3de408427181ea4284a47e719e"><li><code class="notion-inline-code">[&amp;value]</code>：按引用捕获；</li></ul><ul class="notion-list notion-list-disc notion-block-6dfebcdfa8e04066bd540793e203cdf1"><li><code class="notion-inline-code">[=]</code>：默认按值捕获当前作用域变量；</li></ul><ul class="notion-list notion-list-disc notion-block-22d18f8caa574899b77e74892d48470c"><li><code class="notion-inline-code">[&amp;]</code>：默认按引用捕获；</li></ul><ul class="notion-list notion-list-disc notion-block-78f7c283839944bd8e026a4a177eb150"><li><code class="notion-inline-code">[this]</code>：捕获当前对象指针。</li></ul><div class="notion-text notion-block-53ace2646b7d4427b5d7684fb1afcc33">异步任务或延迟回调按引用捕获局部变量时，需要确认回调执行时变量仍然存在。生命周期无法保证时，按值捕获所需数据，或使用明确的共享所有权方案。</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-d719a7e3227040c4ad35d7e9458b3a27" data-id="d719a7e3227040c4ad35d7e9458b3a27"><span><div id="d719a7e3227040c4ad35d7e9458b3a27" class="notion-header-anchor"></div><a class="notion-hash-link" href="#d719a7e3227040c4ad35d7e9458b3a27" title="10.8 std::tuple"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">10.8 <code class="notion-inline-code">std::tuple</code></span></span></h4><div class="notion-text notion-block-204cc78fd7de41599652b3d338dab6c7"><code class="notion-inline-code">std::tuple</code> 是固定大小的异构值集合，可看作 <code class="notion-inline-code">std::pair</code> 的推广。</div><div class="notion-text notion-block-0d7df5d301e54790943fbadf58d99112">常见操作：</div><div class="notion-text notion-block-1c61a43c491b4f9b80b174a0b12715f5">适用场景：</div><ul class="notion-list notion-list-disc notion-block-1ae122ace3604712b0dd4087723e66a3"><li>函数临时返回多个不同类型值；</li></ul><ul class="notion-list notion-list-disc notion-block-7b3be8769ff44fa3a0a2813c25fd5003"><li>组合键；</li></ul><ul class="notion-list notion-list-disc notion-block-bb3e48659b6f4a318e1b66a8f20605f7"><li>泛型编程。</li></ul><div class="notion-text notion-block-b39ec27c9a9e4554ae4b0a702bff36a6">当字段含义稳定且业务语义明显时，定义具名 <code class="notion-inline-code">struct</code> 通常比 <code class="notion-inline-code">tuple</code> 更易读。</div><blockquote class="notion-quote notion-block-76cd09f1181a4e439e1ae08f79c619af"><div><code class="notion-inline-code">std::tuple</code> 示例已使用 C++17 和 <code class="notion-inline-code">-Wall -Wextra -Wpedantic -Werror</code> 编译运行通过。</div></blockquote><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-2d8fb1d7edc74ac4ac87b63df3d72f38" data-id="2d8fb1d7edc74ac4ac87b63df3d72f38"><span><div id="2d8fb1d7edc74ac4ac87b63df3d72f38" class="notion-header-anchor"></div><a class="notion-hash-link" href="#2d8fb1d7edc74ac4ac87b63df3d72f38" title="11. 异常处理与文件 I/O"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">11. 异常处理与文件 I/O</span></span></h3><div class="notion-text notion-block-87099016018947c5baaba76502685261">本章从「异常处理流程」「异常安全保证」和「noexcept」等方面说明异常处理与文件 I/O。</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-550f58e1974e4b1fb0afd1cd49aad992" data-id="550f58e1974e4b1fb0afd1cd49aad992"><span><div id="550f58e1974e4b1fb0afd1cd49aad992" class="notion-header-anchor"></div><a class="notion-hash-link" href="#550f58e1974e4b1fb0afd1cd49aad992" title="11.1 异常处理流程"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">11.1 异常处理流程</span></span></h4><div class="notion-text notion-block-cd6ef30c51044cbea6951c0042b9e283">异常用于报告当前函数无法在本层正常处理的错误：</div><div class="notion-text notion-block-4819553edf6a420db58a0a7600b70d8a">调用者捕获异常：</div><div class="notion-text notion-block-55df3d1e7bf24cdfaf97901c8437ab3a">异常通常按值抛出、按常量引用捕获。异常传播过程中，已经构造完成的局部对象会依次析构，这也是 RAII 能够保证清理的基础。</div><div class="notion-text notion-block-95f0aaf5784644e9b0d008541f617e02">异常适合表示无法在当前层继续完成操作的错误，不应代替普通条件分支或高频控制流程。</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-aebc829167794b1c9b561de074598837" data-id="aebc829167794b1c9b561de074598837"><span><div id="aebc829167794b1c9b561de074598837" class="notion-header-anchor"></div><a class="notion-hash-link" href="#aebc829167794b1c9b561de074598837" title="11.2 异常安全保证"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">11.2 异常安全保证</span></span></h4><div class="notion-text notion-block-4746dafa6a3046de92aa4a21d3157e74">常见异常安全级别：</div><ol start="1" class="notion-list notion-list-numbered notion-block-4ad97447284a421c919bf32940243ed9" style="list-style-type:decimal"><li><b>无泄漏保证：</b>失败时至少不会泄漏资源，对象仍可安全销毁。</li></ol><ol start="2" class="notion-list notion-list-numbered notion-block-9693264912c64e4ab1edfb5181a1bb47" style="list-style-type:decimal"><li><b>基本保证：</b>失败后对象保持有效状态，但值可能发生变化。</li></ol><ol start="3" class="notion-list notion-list-numbered notion-block-55489f66713d4860ba21f9a43f9ec87e" style="list-style-type:decimal"><li><b>强保证：</b>失败后操作效果等同于没有发生。</li></ol><ol start="4" class="notion-list notion-list-numbered notion-block-f518043837ab434089b8dc40429ece7c" style="list-style-type:decimal"><li><b>不抛出保证：</b>操作承诺不会让异常逃逸。</li></ol><div class="notion-text notion-block-453c6f9fde3547a8af8fb8da8ed559af">赋值或批量更新需要强保证时，可以先在临时对象中完成操作，成功后再交换结果。</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-ed0359803e9e4ce486194c63f0500063" data-id="ed0359803e9e4ce486194c63f0500063"><span><div id="ed0359803e9e4ce486194c63f0500063" class="notion-header-anchor"></div><a class="notion-hash-link" href="#ed0359803e9e4ce486194c63f0500063" title="11.3 noexcept"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">11.3 <code class="notion-inline-code">noexcept</code></span></span></h4><div class="notion-text notion-block-a391e264b86f42c2b1a561a99568191a"><code class="notion-inline-code">noexcept</code> 表示函数承诺不让异常传播到调用者：</div><div class="notion-text notion-block-f5ca268044f44fd1b412fdf4c4c9c347">标准库容器在重新分配时，通常更愿意使用不会抛异常的移动构造函数。若异常逃出 <code class="notion-inline-code">noexcept</code> 函数，程序会调用 <code class="notion-inline-code">std::terminate</code>。</div><div class="notion-text notion-block-375d7d4f0f9f42c0af47a14d95906062">析构函数和资源释放操作通常不应抛出异常。清理阶段抛出第二个异常可能直接终止程序。</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-e8a35d8b38714b80a86e752f83bd5bf0" data-id="e8a35d8b38714b80a86e752f83bd5bf0"><span><div id="e8a35d8b38714b80a86e752f83bd5bf0" class="notion-header-anchor"></div><a class="notion-hash-link" href="#e8a35d8b38714b80a86e752f83bd5bf0" title="11.4 文件输入输出"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">11.4 文件输入输出</span></span></h4><div class="notion-text notion-block-0375a153a366488a99f4f5be79b573d1">本节从「写入文件」和「读取文件」两方面说明文件输入输出。</div><h5 class="notion-h notion-h4 notion-h-indent-2 notion-block-1575fbf27f964f3ea9591564900ed385" data-id="1575fbf27f964f3ea9591564900ed385"><span><div id="1575fbf27f964f3ea9591564900ed385" class="notion-header-anchor"></div><a class="notion-hash-link" href="#1575fbf27f964f3ea9591564900ed385" title="11.4.1 写入文件"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">11.4.1 写入文件</span></span></h5><h5 class="notion-h notion-h4 notion-h-indent-2 notion-block-d8fcea76c58744578617d1a3b71c457f" data-id="d8fcea76c58744578617d1a3b71c457f"><span><div id="d8fcea76c58744578617d1a3b71c457f" class="notion-header-anchor"></div><a class="notion-hash-link" href="#d8fcea76c58744578617d1a3b71c457f" title="11.4.2 读取文件"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">11.4.2 读取文件</span></span></h5><div class="notion-text notion-block-0cbc3d150d6441f8a562f037757af5f6">流对象离开作用域时自动关闭文件。打开成功不代表后续读写一定成功，读取格式、写入状态和磁盘错误仍需要检查。</div><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-f852e02f0937417e8a9c2213347c8606" data-id="f852e02f0937417e8a9c2213347c8606"><span><div id="f852e02f0937417e8a9c2213347c8606" class="notion-header-anchor"></div><a class="notion-hash-link" href="#f852e02f0937417e8a9c2213347c8606" title="12. 项目中的使用原则"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">12. 项目中的使用原则</span></span></h3><div class="notion-text notion-block-eb770a35f4164ec494c99104b9367ee4">本章从「先表达所有权，再选择类型」「优先使用标准库抽象」和「头文件与源文件职责」等方面说明项目中的使用原则。</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-2e9c8c73e6bb419990e54a34dcfc6277" data-id="2e9c8c73e6bb419990e54a34dcfc6277"><span><div id="2e9c8c73e6bb419990e54a34dcfc6277" class="notion-header-anchor"></div><a class="notion-hash-link" href="#2e9c8c73e6bb419990e54a34dcfc6277" title="12.1 先表达所有权，再选择类型"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">12.1 先表达所有权，再选择类型</span></span></h4><div class="notion-text notion-block-3345fad08b814227802f0f6e43b2096f">选择指针和对象类型时，先确定谁负责资源生命周期：</div><ul class="notion-list notion-list-disc notion-block-338a8e47fbfc44ab8677007f9da1238c"><li>值对象：资源属于当前对象，复制后彼此独立；</li></ul><ul class="notion-list notion-list-disc notion-block-ad9a792afb5d42a6b4982b2737e64d20"><li><code class="notion-inline-code">unique_ptr</code>：唯一拥有者；</li></ul><ul class="notion-list notion-list-disc notion-block-1696310f5dfc476ba16ae950f3762b75"><li><code class="notion-inline-code">shared_ptr</code>：多个对象共同拥有；</li></ul><ul class="notion-list notion-list-disc notion-block-9022dd983104484282aa8babe137a30c"><li><code class="notion-inline-code">weak_ptr</code>：只观察共享对象；</li></ul><ul class="notion-list notion-list-disc notion-block-5d9ad8c53fbc486a932bbf42c7db15ba"><li>裸指针或引用：通常表示非拥有访问。</li></ul><div class="notion-text notion-block-3d96d60dc36b4566b5537e4f2bb439eb">所有权关系不清晰时，即使代码暂时能够运行，后续也容易出现泄漏、重复释放和悬空访问。</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-917fb36b7b7b4511b63464db0a93e21b" data-id="917fb36b7b7b4511b63464db0a93e21b"><span><div id="917fb36b7b7b4511b63464db0a93e21b" class="notion-header-anchor"></div><a class="notion-hash-link" href="#917fb36b7b7b4511b63464db0a93e21b" title="12.2 优先使用标准库抽象"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">12.2 优先使用标准库抽象</span></span></h4><div class="notion-text notion-block-687b3f2b98a641beadb7f0ec768f3543">优先选择：</div><ul class="notion-list notion-list-disc notion-block-5318b070476b4ce6842a7c23a117c8f7"><li><code class="notion-inline-code">std::string</code> 代替手工字符缓冲区；</li></ul><ul class="notion-list notion-list-disc notion-block-a5c4ac6ed75b45d0bcc1847e47003133"><li><code class="notion-inline-code">std::vector</code> 代替动态数组；</li></ul><ul class="notion-list notion-list-disc notion-block-48c403716bdf494b9882d6424329855b"><li>智能指针代替直接拥有资源的裸指针；</li></ul><ul class="notion-list notion-list-disc notion-block-ebb857b37cd8454daccdd84946360390"><li>标准算法代替重复手写循环；</li></ul><ul class="notion-list notion-list-disc notion-block-360c8168b0b340668cb26aa12190bf1e"><li>RAII 对象代替成对出现的手工申请和释放。</li></ul><div class="notion-text notion-block-c69ee11ebb064ca8844efbf892b20aab">标准库不能消除所有错误，但能够把常见资源管理规则封装进类型系统和对象生命周期中。</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-3488894c283d48fdb6cc1fb7ab761c37" data-id="3488894c283d48fdb6cc1fb7ab761c37"><span><div id="3488894c283d48fdb6cc1fb7ab761c37" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3488894c283d48fdb6cc1fb7ab761c37" title="12.3 头文件与源文件职责"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">12.3 头文件与源文件职责</span></span></h4><div class="notion-text notion-block-3519385a6041443d862f4270d8719805">头文件适合保存：</div><ul class="notion-list notion-list-disc notion-block-917d1f72d93c4e559d2fbfd93b30bd0f"><li>类型声明；</li></ul><ul class="notion-list notion-list-disc notion-block-06ecfc26db2340c3b4a5dd573afe6ba0"><li>函数声明；</li></ul><ul class="notion-list notion-list-disc notion-block-4e4f67e298de4b32aa8d91ece968f891"><li>模板定义；</li></ul><ul class="notion-list notion-list-disc notion-block-efcba46939064a84b843af82fe21389c"><li>必须内联的短函数；</li></ul><ul class="notion-list notion-list-disc notion-block-2b8f5ee8bfae42d9b69f65ac28469372"><li>编译期常量和接口约束。</li></ul><div class="notion-text notion-block-ecb5fa5f15f046219a539398211e16b0">源文件适合保存：</div><ul class="notion-list notion-list-disc notion-block-a1c6deb3852e4985a5a20420a2a39f39"><li>非模板函数定义；</li></ul><ul class="notion-list notion-list-disc notion-block-b64b17bedbed46d3bc15d7b81b38d3ba"><li>具体实现细节；</li></ul><ul class="notion-list notion-list-disc notion-block-20d5055c2803401fbfc3ee5c25796f04"><li>只在当前模块使用的辅助函数和对象。</li></ul><div class="notion-text notion-block-2d6798cdf0b1492880b15d4d4e5373d1">头文件应具有包含保护：</div><div class="notion-text notion-block-a4011126598c44b1ae360ba0eeb9b8d7">或者使用传统宏保护。头文件中避免定义非 <code class="notion-inline-code">inline</code> 的普通全局变量和函数，否则多个翻译单元包含后可能违反单一定义规则。</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-96f8468d82a14a04a6a2934046a56faa" data-id="96f8468d82a14a04a6a2934046a56faa"><span><div id="96f8468d82a14a04a6a2934046a56faa" class="notion-header-anchor"></div><a class="notion-hash-link" href="#96f8468d82a14a04a6a2934046a56faa" title="12.4 编译器警告与运行期检查"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">12.4 编译器警告与运行期检查</span></span></h4><div class="notion-text notion-block-cc7a1081f09749dc81877f559ec74b50">开发阶段应开启较严格的编译器警告，并把警告作为潜在缺陷处理。GCC 和 Clang 项目常用：</div><div class="notion-text notion-block-02f4d54aad50470c8a28d7b457481359">AddressSanitizer、UndefinedBehaviorSanitizer 等工具可以发现越界访问、释放后使用、部分内存泄漏和未定义行为。它们不能替代代码审查，但能显著缩短底层错误的定位时间。</div><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-6c206b2427fc41c187f2ca0a1fdf659b" data-id="6c206b2427fc41c187f2ca0a1fdf659b"><span><div id="6c206b2427fc41c187f2ca0a1fdf659b" class="notion-header-anchor"></div><a class="notion-hash-link" href="#6c206b2427fc41c187f2ca0a1fdf659b" title="13. 数值表示和常见应用"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">13. 数值表示和常见应用</span></span></h3><div class="notion-text notion-block-12a1f075f87f4c1c92ef84fa0954de9f">本章从「二进制、八进制与十六进制字面量」「IEEE 754 浮点表示」和「文本文件与二进制文件」等方面说明数值表示和常见应用。</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-20429792489040fba9bf316243e68ef8" data-id="20429792489040fba9bf316243e68ef8"><span><div id="20429792489040fba9bf316243e68ef8" class="notion-header-anchor"></div><a class="notion-hash-link" href="#20429792489040fba9bf316243e68ef8" title="13.1 二进制、八进制与十六进制字面量"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">13.1 二进制、八进制与十六进制字面量</span></span></h4><div class="notion-text notion-block-fd7f55e383054443acdb75fadcb3eec8">C++ 可以直接书写不同进制的整数字面量：</div><div class="notion-text notion-block-3587162dd8ab4f7da548ca9cb5c59fb7">这些变量保存的数值相同，区别只在源代码中的表示方式。输出格式可以通过 <code class="notion-inline-code">std::dec</code>、<code class="notion-inline-code">std::oct</code> 和 <code class="notion-inline-code">std::hex</code> 控制。</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-02576ce102ad4d4785e59a87c85c3e8e" data-id="02576ce102ad4d4785e59a87c85c3e8e"><span><div id="02576ce102ad4d4785e59a87c85c3e8e" class="notion-header-anchor"></div><a class="notion-hash-link" href="#02576ce102ad4d4785e59a87c85c3e8e" title="13.2 IEEE 754 浮点表示"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">13.2 IEEE 754 浮点表示</span></span></h4><div class="notion-text notion-block-99e6f52ecf954f01a6706267f1334604">常见的 <code class="notion-inline-code">float</code> 和 <code class="notion-inline-code">double</code> 使用 IEEE 754 浮点格式。浮点数由符号位、指数和尾数组成，因此很多十进制小数无法被二进制精确表示。比较计算结果时应使用允许误差，而不是直接依赖 <code class="notion-inline-code">==</code>。</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-f17bf7ffb5b14d19b0fc327115e887ed" data-id="f17bf7ffb5b14d19b0fc327115e887ed"><span><div id="f17bf7ffb5b14d19b0fc327115e887ed" class="notion-header-anchor"></div><a class="notion-hash-link" href="#f17bf7ffb5b14d19b0fc327115e887ed" title="13.3 文本文件与二进制文件"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">13.3 文本文件与二进制文件</span></span></h4><div class="notion-text notion-block-81e32867eb11436cb2b4d9565530fab4">文本模式保存字符表示，便于阅读和跨工具查看；二进制模式按字节保存数据，体积和解析成本通常更低，但必须明确字段布局、字节序和版本。直接写入结构体内存会受到对齐和填充影响，不适合作为稳定文件格式。</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-7b3561b8302749ca9850b45d96426117" data-id="7b3561b8302749ca9850b45d96426117"><span><div id="7b3561b8302749ca9850b45d96426117" class="notion-header-anchor"></div><a class="notion-hash-link" href="#7b3561b8302749ca9850b45d96426117" title="13.4 位运算"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">13.4 位运算</span></span></h4><div class="notion-text notion-block-73d06b16043846338c0488ffd9950684">位运算包括按位与 <code class="notion-inline-code">&amp;</code>、按位或 <code class="notion-inline-code">|</code>、按位异或 <code class="notion-inline-code">^</code>、按位取反 <code class="notion-inline-code">~</code>、左移 <code class="notion-inline-code">&lt;&lt;</code> 和右移 <code class="notion-inline-code">&gt;&gt;</code>。异或满足“相同为 0，不同为 1”，常用于开关位、掩码和成对抵消问题。</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-b4ad2657400c4186a7eca68429481cb8" data-id="b4ad2657400c4186a7eca68429481cb8"><span><div id="b4ad2657400c4186a7eca68429481cb8" class="notion-header-anchor"></div><a class="notion-hash-link" href="#b4ad2657400c4186a7eca68429481cb8" title="13.5 蛇形填数"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">13.5 蛇形填数</span></span></h4><div class="notion-text notion-block-6c9bc90d96de4a079219a9ad54e062ee">蛇形填数可以按“方向数组 + 边界检查 + 已访问标记”实现。每次尝试沿当前方向前进；越界或遇到已填位置时顺时针切换方向，直到填满矩阵。</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-c72a44ad843f42ee80865b00801a2583" data-id="c72a44ad843f42ee80865b00801a2583"><span><div id="c72a44ad843f42ee80865b00801a2583" class="notion-header-anchor"></div><a class="notion-hash-link" href="#c72a44ad843f42ee80865b00801a2583" title="13.6 平闰年判断"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">13.6 平闰年判断</span></span></h4><div class="notion-text notion-block-c84aaea020924a7fa8c0a8a6b408e838">公历闰年的判断条件是：年份能被 400 整除，或能被 4 整除但不能被 100 整除。</div><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-f66e1614d6dc494481216c19a6df0254" data-id="f66e1614d6dc494481216c19a6df0254"><span><div id="f66e1614d6dc494481216c19a6df0254" class="notion-header-anchor"></div><a class="notion-hash-link" href="#f66e1614d6dc494481216c19a6df0254" title="14. 总结"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">14. 总结</span></span></h3><div class="notion-text notion-block-3972b921e5cf449c94c43f21a1d72015">现代 C++ 的重点不只是记住语法，而是明确对象生命周期、所有权、资源释放和接口边界。项目中应优先使用 RAII、标准容器、智能指针和类型安全的接口，再根据性能证据决定是否采用更底层的实现。</div><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-f7ed5f0e1dec4482b6a3d4ee751f65f1" data-id="f7ed5f0e1dec4482b6a3d4ee751f65f1"><span><div id="f7ed5f0e1dec4482b6a3d4ee751f65f1" class="notion-header-anchor"></div><a class="notion-hash-link" href="#f7ed5f0e1dec4482b6a3d4ee751f65f1" title="15. 参考资料"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">15. 参考资料</span></span></h3><ul class="notion-list notion-list-disc notion-block-0f78f16681d348c09e690481aa5fb001"><li><a class="notion-link" href="https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines" target="_blank" rel="noopener noreferrer">C++ Core Guidelines</a></li></ul><ul class="notion-list notion-list-disc notion-block-093a0df369644db19b7f045ee440cae1"><li><a class="notion-link" href="https://eel.is/c++draft/" target="_blank" rel="noopener noreferrer">C++ Working Draft</a></li></ul></main></div>]]></content:encoded>
        </item>
    </channel>
</rss>