{
    "version": "https://jsonfeed.org/version/1",
    "title": "博客",
    "subtitle": "欢迎来访",
    "icon": "https://www.starlinglin.top/images/favicon.ico",
    "description": "StarlingLin的个人博客~",
    "home_page_url": "https://www.starlinglin.top",
    "items": [
        {
            "id": "https://www.starlinglin.top/computer-science/Swift-programme-note/%E6%A4%8B%E9%B8%9FSwift%E7%AC%94%E8%AE%B0%20%EF%BC%830%EF%BC%9A%E5%AD%A6%E4%B9%A0Swift%E5%89%8D/",
            "url": "https://www.starlinglin.top/computer-science/Swift-programme-note/%E6%A4%8B%E9%B8%9FSwift%E7%AC%94%E8%AE%B0%20%EF%BC%830%EF%BC%9A%E5%AD%A6%E4%B9%A0Swift%E5%89%8D/",
            "title": "椋鸟Swift笔记#0：学习Swift前",
            "date_published": "2025-12-18T09:38:00.089Z",
            "content_html": "<div class=\"note info\">\n<p>该系列为本人的学习笔记，主要由本人整理书写而成。部分内容来自 ChaoCode 的视频课程，强烈推荐。</p>\n</div>\n<div class=\"note info\">\n<p>该系列适合有其他语言基础的人观看，基础语法部分描述较少，可能仅列出一些 Swift 的特异点。</p>\n</div>\n<h3 id=\"关于swift语言\"><a class=\"anchor\" href=\"#关于swift语言\">#</a> 关于 Swift 语言</h3>\n<p>Swift 语言是 Apple 平台的开发语言，面世时间很短，远远比不过老牌的编程，非常简洁也非常现代（当然也带来了诸如社区不完善、语法特性更新较快等一些缺点）。</p>\n<p>本系列博客是奔着 SwiftUI 去的，基础语法大概过一下就会到 SwiftUI 部分，所以没有 C++ 等面对对象语言基础的不适合看本系列博客。</p>\n<h3 id=\"你需要准备的\"><a class=\"anchor\" href=\"#你需要准备的\">#</a> 你需要准备的</h3>\n<h4 id=\"1-你需要一台mac\"><a class=\"anchor\" href=\"#1-你需要一台mac\">#</a> 1. 你需要一台 Mac</h4>\n<p>是的，没有 Mac 学习 Swift 寸步难行。你当然可以试着用网页 Swift 或者一些其他方案，但是非常难用，很劝退。用 iPad 上的 Swift PlayGrounds 再外接键盘要好一点，但是也有很多弊端，完全比不上 Mac 开发。</p>\n<h4 id=\"2-你需要一定程度的英文水平\"><a class=\"anchor\" href=\"#2-你需要一定程度的英文水平\">#</a> 2. 你需要一定程度的英文水平</h4>\n<p>Swift 太年轻了，以至于你 “只能在英文社区找到的内容” 会比 C/Cpp 等多的多。很多时候你得读官方文档，纯英文的。</p>\n<p>不过你可以借助 AI 来阅读，但是终究有点麻烦。因为有的时候你不仅仅是要查阅一条固定的信息，而是根据一些模糊的想法或需求去翻来翻去，在专业领域 AI 做这类工作并不可靠，经常出问题。</p>\n<h3 id=\"xcode环境搭建\"><a class=\"anchor\" href=\"#xcode环境搭建\">#</a> Xcode 环境搭建</h3>\n<p>先看看你电脑的 Mac 型号和 OS 版本，比方说一台 18 年 MacBook Air，最高系统版本是 Sonoma 14.8.3，那么支持的 XCode 版本就是</p>\n",
            "tags": [
                "计算机科学",
                "Swift笔记",
                "Swift"
            ]
        },
        {
            "id": "https://www.starlinglin.top/computer-science/Swift-programme-note/%E6%A4%8B%E9%B8%9FSwift%E7%AC%94%E8%AE%B0%20%EF%BC%831%EF%BC%9A%E5%B8%B8%E9%87%8F%E5%8F%98%E9%87%8F%E5%92%8Cprint/",
            "url": "https://www.starlinglin.top/computer-science/Swift-programme-note/%E6%A4%8B%E9%B8%9FSwift%E7%AC%94%E8%AE%B0%20%EF%BC%831%EF%BC%9A%E5%B8%B8%E9%87%8F%E5%8F%98%E9%87%8F%E5%92%8Cprint/",
            "title": "椋鸟Swift笔记#1：常量变量和print",
            "date_published": "2025-12-18T09:06:49.974Z",
            "content_html": "<div class=\"note info\">\n<p>该系列为本人的学习笔记，主要由本人整理书写而成。部分内容来自 ChaoCode 的视频课程，强烈推荐。</p>\n</div>\n",
            "tags": [
                "计算机科学",
                "Swift笔记",
                "Swift"
            ]
        },
        {
            "id": "https://www.starlinglin.top/games/Gal/Untitled/",
            "url": "https://www.starlinglin.top/games/Gal/Untitled/",
            "title": "关于解决在iOS的XP3播放器中由汉化组弹窗导致的闪退问题",
            "date_published": "2025-12-11T18:34:08.860Z",
            "content_html": "<div class=\"note warning\">\n<p>本文不提供任何解包修改工具，请自行 Github 寻找，与本文作者无关。</p>\n</div>\n<div class=\"note warning\">\n<p>本文作者不支持任何形式的游戏倒卖。</p>\n</div>\n<p>iOS 想玩 XP3 格式的游戏，自然绕不开应用市场中的 XP3Player 或者手动侧载 KrKr。但是无论是哪一个，在现在的 iOS 系统中都会出现奇怪的闪退问题（有反馈说更新到 iOS26 可能解决，但我不想更新系统）。</p>\n",
            "tags": [
                "游戏",
                "旮旯",
                "game",
                "Gal"
            ]
        },
        {
            "id": "https://www.starlinglin.top/%E5%85%B3%E4%BA%8E%E6%9C%AC%E5%8D%9A%E5%AE%A2%E6%97%A5%E5%90%8E%E6%9B%B4%E6%96%B0/",
            "url": "https://www.starlinglin.top/%E5%85%B3%E4%BA%8E%E6%9C%AC%E5%8D%9A%E5%AE%A2%E6%97%A5%E5%90%8E%E6%9B%B4%E6%96%B0/",
            "title": "关于本博客日后更新",
            "date_published": "2025-12-03T16:10:23.000Z",
            "content_html": "<p>放置了一年多，差点忘了自己还有一个博客了。</p>\n<p>日后会不定期更新一些内容，但是之前没做完的 cpp 笔记、Linux 笔记、数据结构笔记应该是不会继续更新了：一方面离我现在学到的内容太远；另一方面没有时间去长期频繁更新。</p>\n<p>日后更新应该不会仅限于计算机相关，还有各种各样我喜欢的东西。</p>\n",
            "tags": []
        },
        {
            "id": "https://www.starlinglin.top/games/puzzles/%E8%A7%A3%E8%B0%9C%E6%B8%B8%E6%88%8F-RailBound%E8%BD%A8%E9%81%93%E8%81%94%E7%BB%93-%E6%94%BB%E7%95%A5/",
            "url": "https://www.starlinglin.top/games/puzzles/%E8%A7%A3%E8%B0%9C%E6%B8%B8%E6%88%8F-RailBound%E8%BD%A8%E9%81%93%E8%81%94%E7%BB%93-%E6%94%BB%E7%95%A5/",
            "title": "解谜游戏-RailBound轨道联结-攻略",
            "date_published": "2024-11-28T18:49:29.000Z",
            "content_html": "<div class=\"note warning\">\n<p>此游戏关卡随着版本变动，不能保证时效性。本人游戏版本为 v3.06。</p>\n</div>\n<div class=\"note success\">\n<p>很多题目存在多解，试试自己思考能不能写出不一样的答案。</p>\n</div>\n<p>这个游戏玩法新颖，245 个关卡层层推进，十分有意思。</p>\n<details class=\"primary\"><summary>第一章节</summary><div>\n<p><img data-src=\"1-1.png\" alt=\"1-1\" /></p>\n<p><img data-src=\"1-2.png\" alt=\"1-2\" /></p>\n<p><img data-src=\"1-3.png\" alt=\"1-3\" /></p>\n<p><img data-src=\"1-4.png\" alt=\"1-4\" /></p>\n<p><img data-src=\"1-5.png\" alt=\"1-5\" /></p>\n<p><img data-src=\"1-6.png\" alt=\"1-6\" /></p>\n<p><img data-src=\"1-7.png\" alt=\"1-7\" /></p>\n<p><img data-src=\"1-8.png\" alt=\"1-8\" /></p>\n<p><img data-src=\"1-9.png\" alt=\"1-9\" /></p>\n<p><img data-src=\"1-10.png\" alt=\"1-10\" /></p>\n<p><img data-src=\"1-11.png\" alt=\"1-11\" /></p>\n<p><img data-src=\"1-12.png\" alt=\"1-12\" /></p>\n<p><img data-src=\"1-13.png\" alt=\"1-13\" /></p>\n<p><img data-src=\"1-14.png\" alt=\"1-14\" /></p>\n<p><img data-src=\"1-15.png\" alt=\"1-15\" /></p>\n</div></details>\n<details class=\"info\"><summary>第一章节-扩展关</summary><div>\n<p><img data-src=\"1-11A.png\" alt=\"1-11A\" /></p>\n<p><img data-src=\"1-11B.png\" alt=\"1-11B\" /></p>\n<p><img data-src=\"1-12A.png\" alt=\"1-12A\" /></p>\n<p><img data-src=\"1-13A.png\" alt=\"1-13A\" /></p>\n<p><img data-src=\"1-14A.png\" alt=\"1-14A\" /></p>\n<p><img data-src=\"1-15A.png\" alt=\"1-15A\" /></p>\n</div></details>\n<details class=\"primary\"><summary>第二章节</summary><div>\n<p><img data-src=\"2-1.png\" alt=\"2-1\" /></p>\n<p><img data-src=\"2-2.png\" alt=\"2-2\" /></p>\n<p><img data-src=\"2-3.png\" alt=\"2-3\" /></p>\n<p><img data-src=\"2-4.png\" alt=\"2-4\" /></p>\n<p><img data-src=\"2-5.png\" alt=\"2-5\" /></p>\n<p><img data-src=\"2-6.png\" alt=\"2-6\" /></p>\n<p><img data-src=\"2-7.png\" alt=\"2-7\" /></p>\n<p><img data-src=\"2-8.png\" alt=\"2-8\" /></p>\n<p><img data-src=\"2-9.png\" alt=\"2-9\" /></p>\n</div></details>\n<details class=\"info\"><summary>第二章节-扩展关</summary><div>\n<p><img data-src=\"2-3A.png\" alt=\"2-3A\" /></p>\n<p><img data-src=\"2-3B.png\" alt=\"2-3B\" /></p>\n<p><img data-src=\"2-4A.png\" alt=\"2-4A\" /></p>\n<p><img data-src=\"2-5A.png\" alt=\"2-5A\" /></p>\n<p><img data-src=\"2-5B.png\" alt=\"2-5B\" /></p>\n<p><img data-src=\"2-6A.png\" alt=\"2-6A\" /></p>\n<p><img data-src=\"2-7A.png\" alt=\"2-7A\" /></p>\n<p><img data-src=\"2-7B.png\" alt=\"2-7B\" /></p>\n</div></details>\n<details class=\"primary\"><summary>第三章节</summary><div>\n<p><img data-src=\"3-1.png\" alt=\"3-1\" /></p>\n<p><img data-src=\"3-2.png\" alt=\"3-2\" /></p>\n<p><img data-src=\"3-3.png\" alt=\"3-3\" /></p>\n<p><img data-src=\"3-4.png\" alt=\"3-4\" /></p>\n<p><img data-src=\"3-5.png\" alt=\"3-5\" /></p>\n<p><img data-src=\"3-6.png\" alt=\"3-6\" /></p>\n<p><img data-src=\"3-7.png\" alt=\"3-7\" /></p>\n<p><img data-src=\"3-8.png\" alt=\"3-8\" /></p>\n<p><img data-src=\"3-9.png\" alt=\"3-9\" /></p>\n<p><img data-src=\"3-10.png\" alt=\"3-10\" /></p>\n<p><img data-src=\"3-11.png\" alt=\"3-11\" /></p>\n</div></details>\n<details class=\"info\"><summary>第三章节-扩展关</summary><div>\n<p><img data-src=\"3-3A.png\" alt=\"3-3A\" /></p>\n<p><img data-src=\"3-7A.png\" alt=\"3-7A\" /></p>\n<p><img data-src=\"3-8A.png\" alt=\"3-8A\" /></p>\n<p><img data-src=\"3-8B.png\" alt=\"3-8B\" /></p>\n<p><img data-src=\"3-10A.png\" alt=\"3-10A\" /></p>\n<p><img data-src=\"3-10B.png\" alt=\"3-10B\" /></p>\n<p><img data-src=\"3-10C.png\" alt=\"3-10C\" /></p>\n<p><img data-src=\"3-11A.png\" alt=\"3-11A\" /></p>\n<p><img data-src=\"3-11B.png\" alt=\"3-11B\" /></p>\n</div></details>\n<details class=\"primary\"><summary>第四章节</summary><div>\n<p><img data-src=\"4-1.png\" alt=\"4-1\" /></p>\n<p><img data-src=\"4-2.png\" alt=\"4-2\" /></p>\n<p><img data-src=\"4-3.png\" alt=\"4-3\" /></p>\n<p><img data-src=\"4-4.png\" alt=\"4-4\" /></p>\n<p><img data-src=\"4-5.png\" alt=\"4-5\" /></p>\n<p><img data-src=\"4-6.png\" alt=\"4-6\" /></p>\n<p><img data-src=\"4-7.png\" alt=\"4-7\" /></p>\n<p><img data-src=\"4-8.png\" alt=\"4-8\" /></p>\n<p><img data-src=\"4-9.png\" alt=\"4-9\" /></p>\n</div></details>\n<details class=\"info\"><summary>第四章节-扩展关</summary><div>\n<p><img data-src=\"4-3A.png\" alt=\"4-3A\" /></p>\n<p><img data-src=\"4-3B.png\" alt=\"4-3B\" /></p>\n<p><img data-src=\"4-4A.png\" alt=\"4-4A\" /></p>\n<p><img data-src=\"4-5A.png\" alt=\"4-5A\" /></p>\n<p><img data-src=\"4-6A.png\" alt=\"4-6A\" /></p>\n<p><img data-src=\"4-6B.png\" alt=\"4-6B\" /></p>\n<p><img data-src=\"4-6C.png\" alt=\"4-6C\" /></p>\n<p><img data-src=\"4-7A.png\" alt=\"4-7A\" /></p>\n<p><img data-src=\"4-7B.png\" alt=\"4-7B\" /></p>\n<p><img data-src=\"4-8A.png\" alt=\"4-8A\" /></p>\n<p><img data-src=\"4-8B.png\" alt=\"4-8B\" /></p>\n<p><img data-src=\"4-9A.png\" alt=\"4-9A\" /></p>\n<p><img data-src=\"4-9B.png\" alt=\"4-9B\" /></p>\n</div></details>\n<details class=\"primary\"><summary>第五章节</summary><div>\n<p><img data-src=\"5-1.png\" alt=\"5-1\" /></p>\n<p><img data-src=\"5-2.png\" alt=\"5-2\" /></p>\n<p><img data-src=\"5-3.png\" alt=\"5-3\" /></p>\n<p><img data-src=\"5-4.png\" alt=\"5-4\" /></p>\n<p><img data-src=\"5-5.png\" alt=\"5-5\" /></p>\n<p><img data-src=\"5-6.png\" alt=\"5-6\" /></p>\n<p><img data-src=\"5-7.png\" alt=\"5-7\" /></p>\n<p><img data-src=\"5-8.png\" alt=\"5-8\" /></p>\n</div></details>\n<details class=\"info\"><summary>第五章节-扩展关</summary><div>\n<p><img data-src=\"5-3A.png\" alt=\"5-3A\" /></p>\n<p><img data-src=\"5-3B.png\" alt=\"5-3B\" /></p>\n<p><img data-src=\"5-4A.png\" alt=\"5-4A\" /></p>\n<p><img data-src=\"5-4B.png\" alt=\"5-4B\" /></p>\n<p><img data-src=\"5-4C.png\" alt=\"5-4C\" /></p>\n<p><img data-src=\"5-5A.png\" alt=\"5-5A\" /></p>\n<p><img data-src=\"5-5B.png\" alt=\"5-5B\" /></p>\n<p><img data-src=\"5-6A.png\" alt=\"5-6A\" /></p>\n<p><img data-src=\"5-6B.png\" alt=\"5-6B\" /></p>\n<p><img data-src=\"5-7A.png\" alt=\"5-7A\" /></p>\n<p><img data-src=\"5-8A.png\" alt=\"5-8A\" /></p>\n</div></details>\n<details class=\"primary\"><summary>第六章节</summary><div>\n<p><img data-src=\"6-1.png\" alt=\"6-1\" /></p>\n<p><img data-src=\"6-2.png\" alt=\"6-2\" /></p>\n<p><img data-src=\"6-3.png\" alt=\"6-3\" /></p>\n<p><img data-src=\"6-4.png\" alt=\"6-4\" /></p>\n<p><img data-src=\"6-5.png\" alt=\"6-5\" /></p>\n<p><img data-src=\"6-6.png\" alt=\"6-6\" /></p>\n<p><img data-src=\"6-7.png\" alt=\"6-7\" /></p>\n<p><img data-src=\"6-8.png\" alt=\"6-8\" /></p>\n<p><img data-src=\"6-9.png\" alt=\"6-9\" /></p>\n<p><img data-src=\"6-10.png\" alt=\"6-10\" /></p>\n</div></details>\n<details class=\"info\"><summary>第六章节-扩展关</summary><div>\n<p><img data-src=\"6-2A.png\" alt=\"6-2A\" /></p>\n<p><img data-src=\"6-3A.png\" alt=\"6-3A\" /></p>\n<p><img data-src=\"6-3B.png\" alt=\"6-3B\" /></p>\n<p><img data-src=\"6-4A.png\" alt=\"6-4A\" /></p>\n<p><img data-src=\"6-4B.png\" alt=\"6-4B\" /></p>\n<p><img data-src=\"6-4C.png\" alt=\"6-4C\" /></p>\n<p><img data-src=\"6-5A.png\" alt=\"6-5A\" /></p>\n<p><img data-src=\"6-6A.png\" alt=\"6-6A\" /></p>\n<p><img data-src=\"6-7A.png\" alt=\"6-7A\" /></p>\n<p><img data-src=\"6-8A.png\" alt=\"6-8A\" /></p>\n<p><img data-src=\"6-8B.png\" alt=\"6-8B\" /></p>\n<p><img data-src=\"6-9A.png\" alt=\"6-9A\" /></p>\n<p><img data-src=\"6-9B.png\" alt=\"6-9B\" /></p>\n<p><img data-src=\"6-9C.png\" alt=\"6-9C\" /></p>\n<p><img data-src=\"6-9D.png\" alt=\"6-9D\" /></p>\n<p><img data-src=\"6-10A.png\" alt=\"6-10A\" /></p>\n</div></details>\n<details class=\"primary\"><summary>第七章节</summary><div>\n<p><img data-src=\"7-1.png\" alt=\"7-1\" /></p>\n<p><img data-src=\"7-2.png\" alt=\"7-2\" /></p>\n<p><img data-src=\"7-3.png\" alt=\"7-3\" /></p>\n<p><img data-src=\"7-4.png\" alt=\"7-4\" /></p>\n<p><img data-src=\"7-5.png\" alt=\"7-5\" /></p>\n<p><img data-src=\"7-6.png\" alt=\"7-6\" /></p>\n<p><img data-src=\"7-7.png\" alt=\"7-7\" /></p>\n<p><img data-src=\"7-8.png\" alt=\"7-8\" /></p>\n<p><img data-src=\"7-9.png\" alt=\"7-9\" /></p>\n</div></details>\n<details class=\"info\"><summary>第七章节-扩展关</summary><div>\n<p><img data-src=\"7-3A.png\" alt=\"7-3A\" /></p>\n<p><img data-src=\"7-3B.png\" alt=\"7-3B\" /></p>\n<p><img data-src=\"7-4A.png\" alt=\"7-4A\" /></p>\n<p><img data-src=\"7-4B.png\" alt=\"7-4B\" /></p>\n<p><img data-src=\"7-5A.png\" alt=\"7-5A\" /></p>\n<p><img data-src=\"7-6A.png\" alt=\"7-6A\" /></p>\n<p><img data-src=\"7-7A.png\" alt=\"7-7A\" /></p>\n<p><img data-src=\"7-7B.png\" alt=\"7-7B\" /></p>\n<p><img data-src=\"7-7C.png\" alt=\"7-7C\" /></p>\n</div></details>\n<details class=\"primary\"><summary>第八章节</summary><div>\n<p><img data-src=\"8-1.png\" alt=\"8-1\" /></p>\n<p><img data-src=\"8-2.png\" alt=\"8-2\" /></p>\n<p><img data-src=\"8-3.png\" alt=\"8-3\" /></p>\n<p><img data-src=\"8-4.png\" alt=\"8-4\" /></p>\n<p><img data-src=\"8-5.png\" alt=\"8-5\" /></p>\n<p><img data-src=\"8-6.png\" alt=\"8-6\" /></p>\n<p><img data-src=\"8-7.png\" alt=\"8-7\" /></p>\n<p><img data-src=\"8-8.png\" alt=\"8-8\" /></p>\n</div></details>\n<details class=\"info\"><summary>第八章节-扩展关</summary><div>\n<p><img data-src=\"8-1A.png\" alt=\"8-1A\" /></p>\n<p><img data-src=\"8-2A.png\" alt=\"8-2A\" /></p>\n<p><img data-src=\"8-2B.png\" alt=\"8-2B\" /></p>\n<p><img data-src=\"8-3A.png\" alt=\"8-3A\" /></p>\n<p><img data-src=\"8-4A.png\" alt=\"8-4A\" /></p>\n<p><img data-src=\"8-4B.png\" alt=\"8-4B\" /></p>\n<p><img data-src=\"8-5A.png\" alt=\"8-5A\" /></p>\n<p><img data-src=\"8-5B.png\" alt=\"8-5B\" /></p>\n<p><img data-src=\"8-6A.png\" alt=\"8-6A\" /></p>\n<p><img data-src=\"8-7A.png\" alt=\"8-7A\" /></p>\n<p><img data-src=\"8-8A.png\" alt=\"8-8A\" /></p>\n</div></details>\n<details class=\"primary\"><summary>第九章节</summary><div>\n<p><img data-src=\"9-1.png\" alt=\"9-1\" /></p>\n<p><img data-src=\"9-2.png\" alt=\"9-2\" /></p>\n<p><img data-src=\"9-3.png\" alt=\"9-3\" /></p>\n<p><img data-src=\"9-4.png\" alt=\"9-4\" /></p>\n<p><img data-src=\"9-5.png\" alt=\"9-5\" /></p>\n<p><img data-src=\"9-6.png\" alt=\"9-6\" /></p>\n<p><img data-src=\"9-7.png\" alt=\"9-7\" /></p>\n<p><img data-src=\"9-8.png\" alt=\"9-8\" /></p>\n<p><img data-src=\"9-9.png\" alt=\"9-9\" /></p>\n<p><img data-src=\"9-10.png\" alt=\"9-10\" /></p>\n<p><img data-src=\"9-11.png\" alt=\"9-11\" /></p>\n</div></details>\n<details class=\"info\"><summary>第九章节-扩展关</summary><div>\n<p><img data-src=\"9-2A.png\" alt=\"9-2A\" /></p>\n<p><img data-src=\"9-3A.png\" alt=\"9-3A\" /></p>\n<p><img data-src=\"9-8A.png\" alt=\"9-8A\" /></p>\n<p><img data-src=\"9-9A.png\" alt=\"9-9A\" /></p>\n<p><img data-src=\"9-10A.png\" alt=\"9-10A\" /></p>\n<p><img data-src=\"9-10B.png\" alt=\"9-10B\" /></p>\n<p><img data-src=\"9-11A.png\" alt=\"9-11A\" /></p>\n<p><img data-src=\"9-11B.png\" alt=\"9-11B\" /></p>\n</div></details>\n<details class=\"primary\"><summary>第十章节</summary><div>\n<p><img data-src=\"10-1.png\" alt=\"10-1\" /></p>\n<p><img data-src=\"10-2.png\" alt=\"10-2\" /></p>\n<p><img data-src=\"10-3.png\" alt=\"10-3\" /></p>\n<p><img data-src=\"10-4.png\" alt=\"10-4\" /></p>\n<p><img data-src=\"10-5.png\" alt=\"10-5\" /></p>\n<p><img data-src=\"10-6.png\" alt=\"10-6\" /></p>\n<p><img data-src=\"10-7.png\" alt=\"10-7\" /></p>\n<p><img data-src=\"10-8.png\" alt=\"10-8\" /></p>\n</div></details>\n<details class=\"info\"><summary>第十章节-扩展关</summary><div>\n<p><img data-src=\"10-1A.png\" alt=\"10-1A\" /></p>\n<p><img data-src=\"10-2A.png\" alt=\"10-2A\" /></p>\n<p><img data-src=\"10-2B.png\" alt=\"10-2B\" /></p>\n<p><img data-src=\"10-5A.png\" alt=\"10-5A\" /></p>\n<p><img data-src=\"10-6A.png\" alt=\"10-6A\" /></p>\n</div></details>\n<details class=\"primary\"><summary>第十一章节</summary><div>\n<p><img data-src=\"11-1.png\" alt=\"11-1\" /></p>\n<p><img data-src=\"11-2.png\" alt=\"11-2\" /></p>\n<p><img data-src=\"11-3.png\" alt=\"11-3\" /></p>\n<p><img data-src=\"11-4.png\" alt=\"11-4\" /></p>\n<p><img data-src=\"11-5.png\" alt=\"11-5\" /></p>\n<p><img data-src=\"11-6.png\" alt=\"11-6\" /></p>\n<p><img data-src=\"11-7.png\" alt=\"11-7\" /></p>\n<p><img data-src=\"11-8.png\" alt=\"11-8\" /></p>\n<p><img data-src=\"11-9.png\" alt=\"11-9\" /></p>\n<p><img data-src=\"11-10.png\" alt=\"11-10\" /></p>\n</div></details>\n<details class=\"info\"><summary>第十一章节-扩展关</summary><div>\n<p><img data-src=\"11-2A.png\" alt=\"11-2A\" /></p>\n<p><img data-src=\"11-2B.png\" alt=\"11-2B\" /></p>\n<p><img data-src=\"11-6A.png\" alt=\"11-6A\" /></p>\n<p><img data-src=\"11-7A.png\" alt=\"11-7A\" /></p>\n<p><img data-src=\"11-8A.png\" alt=\"11-8A\" /></p>\n<p><img data-src=\"11-8B.png\" alt=\"11-8B\" /></p>\n<p><img data-src=\"11-9A.png\" alt=\"11-9A\" /></p>\n<p><img data-src=\"11-9B.png\" alt=\"11-9B\" /></p>\n</div></details>\n<details class=\"primary\"><summary>第十二章节</summary><div>\n<p><img data-src=\"12-1.png\" alt=\"12-1\" /></p>\n<p><img data-src=\"12-2.png\" alt=\"12-2\" /></p>\n<p><img data-src=\"12-3.png\" alt=\"12-3\" /></p>\n<p><img data-src=\"12-4.png\" alt=\"12-4\" /></p>\n<p><img data-src=\"12-5.png\" alt=\"12-5\" /></p>\n<p><img data-src=\"12-6.png\" alt=\"12-6\" /></p>\n<p><img data-src=\"12-7.png\" alt=\"12-7\" /></p>\n<p><img data-src=\"12-8.png\" alt=\"12-8\" /></p>\n<p><img data-src=\"12-9.png\" alt=\"12-9\" /></p>\n<p><img data-src=\"12-10.png\" alt=\"12-10\" /></p>\n</div></details>\n<details class=\"info\"><summary>第十二章节-扩展关</summary><div>\n<p><img data-src=\"12-1A.png\" alt=\"12-1A\" /></p>\n<p><img data-src=\"12-1B.png\" alt=\"12-1B\" /></p>\n<p><img data-src=\"12-3A.png\" alt=\"12-3A\" /></p>\n<p><img data-src=\"12-4A.png\" alt=\"12-4A\" /></p>\n<p><img data-src=\"12-5A.png\" alt=\"12-5A\" /></p>\n<p><img data-src=\"12-5B.png\" alt=\"12-5B\" /></p>\n<p><img data-src=\"12-6A.png\" alt=\"12-6A\" /></p>\n<p><img data-src=\"12-6B.png\" alt=\"12-6B\" /></p>\n<p><img data-src=\"12-7A.png\" alt=\"12-7A\" /></p>\n<p><img data-src=\"12-8A.png\" alt=\"12-8A\" /></p>\n<p><img data-src=\"12-8B.png\" alt=\"12-8B\" /></p>\n</div></details>\n<details class=\"success\"><summary>井号章节</summary><div>\n<p>这个章节余量轨道相当多，可以说是随便摆。</p>\n<p><img data-src=\"#-1.png\" alt=\"#-1\" /></p>\n<p><img data-src=\"#-2.png\" alt=\"#-2\" /></p>\n<p><img data-src=\"#-3.png\" alt=\"#-3\" /></p>\n<p><img data-src=\"#-4.png\" alt=\"#-4\" /></p>\n<p><img data-src=\"#-5.png\" alt=\"#-5\" /></p>\n<p><img data-src=\"#-6.png\" alt=\"#-6\" /></p>\n<p><img data-src=\"#-7.png\" alt=\"#-7\" /></p>\n<p><img data-src=\"#-8.png\" alt=\"#-8\" /></p>\n<p><img data-src=\"#-9.png\" alt=\"#-9\" /></p>\n<p><img data-src=\"#-10.png\" alt=\"#-10\" /></p>\n<p><img data-src=\"#-11.png\" alt=\"#-11\" /></p>\n<p><img data-src=\"#-12.png\" alt=\"#-12\" /></p>\n</div></details>\n<details class=\"danger\"><summary>彩蛋章节</summary><div>\n<p>我们回到目录画面，然后在左边看到这样一个施工图标。（其实是 credit）</p>\n<p><img data-src=\"menu.png\" alt=\"menu\" /></p>\n<p>点进去之后拖到最底下，这里我们看到最后一个隐藏关卡 “❤️”。</p>\n<p><img data-src=\"egg.png\" alt=\"egg\" /></p>\n<p>这一关解法如下：</p>\n<p><img data-src=\"egg-ans.png\" alt=\"egg-ans\" /></p>\n</div></details>\n",
            "tags": [
                "游戏",
                "解谜游戏",
                "game",
                "puzzle"
            ]
        },
        {
            "id": "https://www.starlinglin.top/computer-science/misc/%E8%BD%AC%E8%BD%BD%C2%B7%E7%AE%97%E6%B3%95%E6%8F%8F%E8%BF%B0%E8%AF%AD%E8%A8%80ADL/",
            "url": "https://www.starlinglin.top/computer-science/misc/%E8%BD%AC%E8%BD%BD%C2%B7%E7%AE%97%E6%B3%95%E6%8F%8F%E8%BF%B0%E8%AF%AD%E8%A8%80ADL/",
            "title": "转载·算法描述语言ADL",
            "date_published": "2024-09-21T07:26:09.000Z",
            "content_html": "<div class=\"note info\">\n<p>转载自《数据结构》（第三版）- 刘大有、杨博等。</p>\n</div>\n<p><strong>用算法描述语言 ADL 书写算法的格式及规定如下：</strong></p>\n<pre><code>算法&lt;算法名&gt;(变量i1,···,变量in.变量j,···,变量jn)\n// &lt;算法的概括说明&gt;或者/*&lt;算法的概括说明&gt;*/\n&lt;步骤名&gt;.[&lt;本步骤的概括说明&gt;]\n\t&lt;操作1&gt; //&lt;操作1的解释&gt;或者/*&lt;操作1的解释&gt;*/\n\t\t或者(操作1的解释)或者&lt;无解释&gt;\n\t···\n\t&lt;操作J1&gt; //&lt;操作J1的解释&gt;或者/*&lt;操作J1的解释&gt;*/\n\t\t或者(操作J1的解释)或者&lt;无解释&gt;\n···\n&lt;步骤名&gt;.[&lt;本步骤的概括说明&gt;]\n\t&lt;操作1&gt; //&lt;操作1的解释&gt;或者/*&lt;操作1的解释&gt;*/\n\t\t或者(操作1的解释)或者&lt;无解释&gt;\n\t···\n\t&lt;操作Jk&gt; //&lt;操作Jk的解释&gt;或者/*&lt;操作Jk的解释&gt;*/\n\t\t或者(操作Jk的解释)或者&lt;无解释&gt;|\n</code></pre>\n<p><strong>下面是对上述书写格式给出具体解释：</strong></p>\n<ol>\n<li>\n<p><strong>关于 “&lt;算法名&gt;(变量 i1,・・・, 变量 in. 变量 j,・・・, 变量 jn)” 的解释</strong></p>\n<pre><code>  &lt;算法名&gt;是由字母和数字组成的有限字符串，并且字符串中的第一个符号必须是字母。\n  在变量表中，变量ik为输入变量.1≤k≤m,m≥0,当m=O时.表示无输入变量;变量jk为输出变量，1≤k≤n,n≥1。\n</code></pre>\n</li>\n<li>\n<p><strong>关于 &lt;算法的概括说明&gt; 的解释</strong></p>\n<pre><code>  在算法的变量表后对整个算法进行概括说明，说明中应包含算法的主要思想,对算法功能和其变量的解释等。\n  说明较短时使用//，较长时使用/**/\n</code></pre>\n</li>\n<li>\n<p><strong>关于算法步骤的解释</strong></p>\n<pre><code>  算法的每一步骤都要有步骤名，步骤名由&lt;算法名或算法名缩写&gt;&lt;数字&gt;组成。\n  步骤名后面的方括号内是对该步骤所执行操作的高度概括。\n  方括号后是本步骤的一系列操作，每个操作由ADL语句给出,若某操作难于理解则需在其后对其做出解释。\n</code></pre>\n</li>\n<li>\n<p><strong>关于符号 “|” 的解释</strong></p>\n<pre><code>  每个算法都需要用符号“|”表示其被书写完毕，也就是说，符号“|”作为对应算法被书写完毕的结束符。\n  注意算法不一定在符号“|”处运行结束。\n</code></pre>\n</li>\n<li>\n<p><strong>可使用的算术运算符</strong></p>\n<pre><code>  +、-、*、x、/、DIV、MOD、⌊⌋(取地板运算,如⌊x⌋的值是小于等于x的最大整数)、\n  ⌈⌉(取天棚运算，如⌈x⌉的值是大于等于x的最小整数）.....\n</code></pre>\n</li>\n<li>\n<p><strong>可用的关系、逻辑运算符、逻辑常量、集合运算符</strong></p>\n<pre><code>关系运算符(＝、≠、＜、＞、≥、≤ ...)\n逻辑运算符(AND、OR、NOT)\n逻排常量(true、false)\n集合运算符(∩、∪、-(差)...)\n</code></pre>\n</li>\n<li>\n<p><strong>结束符</strong></p>\n<pre><code> 通常每条语句(或每个操作)都用&quot;.”作为结束符。\n 但在能判断语句结束的位置可略去“.”。\n</code></pre>\n</li>\n<li>\n<p><strong>关于注释语句</strong></p>\n<pre><code>注释语句有以下3种形式:\n  1.较短的注释语句(注释内容不超过一行)用符号“//”开头,后面是具体注释的内容。\n  2.较长的注释语句用符号“/*”开头,中间是具体注释的内容,用符号“*/”结尾。\n  3.注释语句用左小括号“(&quot;开头，中间是具体的注释或说明内容，用右小括号“)”结尾。\n</code></pre>\n</li>\n<li>\n<p><strong>关于赋值语句</strong></p>\n<pre><code> 形如a←b,其中a是变量,b是表达式或变量;\n a↔b表示交换变量a和变量b的内容;\n a←b←c,表示既将c的值赋给变量a,又将其值赋给变量b。\n</code></pre>\n</li>\n<li>\n<p><strong>关于条件语句</strong></p>\n<pre><code>1.IF(或如果,或若)&lt;逻辑表达式&gt; THEN(或“，则”)(语句...语句m).\n2.IF(或如果,或若)&lt;逻辑表达式&gt;\n\tTHEN(或“，则&quot;)(语句...语句m).\n\tELSE(或“;否则”)(语句...语句n).\n其中m,n≥1。\n3.CASE DO\n\t\t(&lt;逻辑表达式 1&gt;:(语句1...语句n).\n\t\t       ···\n\t\t&lt;逻辑表达式m&gt;:(语句...语句nm )).\n其中,n≥1,m≥1,1≤i≤m。\n</code></pre>\n</li>\n<li>\n<p><strong>关于循环语句</strong></p>\n<pre><code>\t1.WHILE&lt;逻辑表达式&gt;DO(语句1. ..语句n).\n其中，n≥1。\n\t2.FOR&lt;变量&gt;=&lt;算术表达式1&gt; T0&lt;算术表达式2&gt;STEP&lt;算术表达式3&gt;\n\t\t\t\tDO(语句1. ... 语句n).\n其中,n≥1。若&lt;算术表达式3&gt;=1,则“STEP&lt;算术表达式3&gt;&quot;可略去。\n\t3.FOR V&lt;变量&gt;∈&lt;集合&gt; DO (语句...语句n).路\n其中,n≥1。\n</code></pre>\n</li>\n<li>\n<p><strong>关于转移语句</strong></p>\n<pre><code>GOTO &lt;步骤名&gt;.\n</code></pre>\n</li>\n<li>\n<p><strong>关于 EXIT 语句</strong></p>\n<pre><code>  可用在通常的结束条件满足之前，用来结束WHILE或FOR循环的执行。\n  EXIT语句使得程序转移到紧接在包含EXIT的(最内层的)WHILE或者FOR循环后面的第一个语句。\n</code></pre>\n</li>\n<li>\n<p><strong>关于圆括号</strong></p>\n<pre><code>当且仅当圆括号中只有1条语句时，圆括号可以省略。\n</code></pre>\n</li>\n<li>\n<p><strong>关于输入、输出语句</strong></p>\n<pre><code>输人语句为\n\tREAD(x)\n表示读取输人值赋给变量x。\n输出语句为\n\tPRINT(&lt;表达式&gt;)\n或\n\tPRINT&lt;字符串常量&gt;\n</code></pre>\n</li>\n</ol>\n",
            "tags": [
                "计算机科学",
                "杂项",
                "算法"
            ]
        },
        {
            "id": "https://www.starlinglin.top/computer-science/Cpp-programme-note/%E6%A4%8B%E9%B8%9FC++%E7%AC%94%E8%AE%B0%20%EF%BC%837%EF%BC%9A%E6%A0%87%E5%87%86%E6%A8%A1%E6%9D%BF%E5%BA%93STL%E5%88%9D%E8%AF%86/",
            "url": "https://www.starlinglin.top/computer-science/Cpp-programme-note/%E6%A4%8B%E9%B8%9FC++%E7%AC%94%E8%AE%B0%20%EF%BC%837%EF%BC%9A%E6%A0%87%E5%87%86%E6%A8%A1%E6%9D%BF%E5%BA%93STL%E5%88%9D%E8%AF%86/",
            "title": "椋鸟C++笔记#7：标准模板库STL初识",
            "date_published": "2024-09-11T13:30:34.000Z",
            "content_html": "<div class=\"note warning\">\n<p>本系列暴死，不会更新了。</p>\n</div>\n<div class=\"note info\">\n<p>该系列为本人的学习笔记，主要由本人整理书写而成。部分内容来自教材、视频课程等，不能保证完全原创性。</p>\n</div>\n<p>萌新的学习笔记，写错了恳请斧正。</p>\n<h3 id=\"标准模板库standard-template-library\"><a class=\"anchor\" href=\"#标准模板库standard-template-library\">#</a> 标准模板库（Standard Template Library）</h3>\n<p>标准模板库 STL，是 C++ 标准库的一个非常重要的组成成分。它的作用就类似于一个工具箱，里面有很多现成的模板 “工具”，帮助我们更方便的处理数据。</p>\n<h3 id=\"stl的版本\"><a class=\"anchor\" href=\"#stl的版本\">#</a> STL 的版本</h3>\n<p>STL 最早是由 Alexander Stepanov 和 Meng Lee 在惠普实验室开发出来的，是完全开源的，这个原始版本也是现在所有 STL 的始祖。</p>\n<h4 id=\"pj版\"><a class=\"anchor\" href=\"#pj版\">#</a> P.J. 版</h4>\n<p>这个版本是 P.J. Plauger 开发的，不允许公开及修改。这个版本是 STL 最早期的版本之一，代码可读性差而且符号命名比较奇怪。但是 Windows Visual C++ 采用的是这个版本。</p>\n<h4 id=\"rw版\"><a class=\"anchor\" href=\"#rw版\">#</a> RW 版</h4>\n<p>这个由 Rogue Wave 公司开发的版本，不允许公开及修改。这个版本着重于与商业环境的集成，通常用于大型企业级项目中。功能非常丰富且跨平台支持性极好。</p>\n<h4 id=\"sgi版\"><a class=\"anchor\" href=\"#sgi版\">#</a> SGI 版</h4>\n<p>SGI 版本由 Silicon Graphics 公司开发，这个版本是标准 C++STL 的基础，也是使用最多的 STL 版本。这个版本是开源的，其设计高效而且稳定，代码风格优秀命名合理。是适合初学者的版本。</p>\n<h3 id=\"stl的组成部分\"><a class=\"anchor\" href=\"#stl的组成部分\">#</a> STL 的组成部分</h3>\n<ol>\n<li><strong>容器</strong>：就像不同类型的 “数据盒子”，用来存放各种数据，比如动态数组、链表、集合等。</li>\n<li><strong>迭代器</strong>：是用来从这些 “数据盒子” 里拿数据的 “工具”，就像指针，能帮助我们遍历和操作里面的内容。</li>\n<li><strong>算法</strong>：是一组现成的 “操作指令”，用来对数据进行排序、查找、复制等处理。</li>\n<li><strong>仿函数</strong>：仿函数就是一个带有 “函数功能” 的对象，能像函数一样被调用。</li>\n<li><strong>配接器</strong>：用来改变容器、迭代器或仿函数行为的工具。</li>\n<li><strong>空间配置器</strong>：类似于内存池，负责为容器开辟和释放内存。</li>\n</ol>\n",
            "tags": [
                "计算机科学",
                "C++笔记",
                "C++",
                "STL"
            ]
        },
        {
            "id": "https://www.starlinglin.top/computer-science/Cpp-programme-note/%E6%A4%8B%E9%B8%9FC++%E7%AC%94%E8%AE%B0%20%EF%BC%838%EF%BC%9A%E6%A0%87%E5%87%86%E5%BA%93%E4%B8%AD%E7%9A%84string%E7%B1%BBstring/",
            "url": "https://www.starlinglin.top/computer-science/Cpp-programme-note/%E6%A4%8B%E9%B8%9FC++%E7%AC%94%E8%AE%B0%20%EF%BC%838%EF%BC%9A%E6%A0%87%E5%87%86%E5%BA%93%E4%B8%AD%E7%9A%84string%E7%B1%BBstring/",
            "title": "椋鸟C++笔记#8：标准库中的string类",
            "date_published": "2024-09-11T13:30:34.000Z",
            "content_html": "<div class=\"note warning\">\n<p>本系列暴死，不会更新了。</p>\n</div>\n<div class=\"note warning\">\n<p>本篇尚未完工</p>\n</div>\n<div class=\"note info\">\n<p>该系列为本人的学习笔记，主要由本人整理书写而成。部分内容来自教材、视频课程等，不能保证完全原创性。</p>\n</div>\n<p>萌新的学习笔记，写错了恳请斧正。</p>\n<h3 id=\"c语言里的字符串\"><a class=\"anchor\" href=\"#c语言里的字符串\">#</a> C 语言里的字符串</h3>\n<p>在学 C 语言的时候，我们使用过字符串，当时字符串是以 '\\0' 结尾的字符的集合。同时，C 语言标准库里还提供了一些 str 函数用于处理字符串。但是这种字符串的使用有很大的缺陷：</p>\n<ol>\n<li>关于字符串处理的库函数和字符串本身是分离的，<strong>不符合面向对象的思想</strong>。</li>\n<li><strong>内存管理非常复杂</strong>，依赖于程序员对每一个字符串进行分配和释放内存，容易出现<strong>内存泄露或者越界访问</strong>。</li>\n<li>很多 str 函数的操作并没有那么方便，想实现一些功能会有比较繁琐的操作，还要考虑内存大小的问题容易出错。</li>\n<li>C 语言的字符串并不方便动态扩展，需要手动重新分配内存。</li>\n<li><mark>虽然本质上 C 语言的字符串就是一个字符数组，但是这里字符串和字符数组表现出来的性质是有所不同的（详见 C 语言笔记 #20 的最后一个样例），这导致两者容易被搞混！</mark></li>\n</ol>\n<h3 id=\"c中的string类\"><a class=\"anchor\" href=\"#c中的string类\">#</a> C++ 中的 string 类</h3>\n<h4 id=\"string类是什么\"><a class=\"anchor\" href=\"#string类是什么\">#</a> string 类是什么</h4>\n<blockquote>\n<p>C++ 中的 <code>std::string</code>  类是标准库中用于处理字符串的类。它提供了一种高效、灵活且安全的方式来操作字符序列，替代了 C 语言中基于 <code>char*</code>  的字符串。 <code>std::string</code>  自动管理内存，支持动态扩展，避免了手动内存分配的复杂性。它提供了丰富的成员函数和操作符重载，如拼接、查找、截取、比较等操作，极大简化了字符串的处理。此外， <code>std::string</code>  还兼容 STL 的容器风格，支持迭代器和各种算法。</p>\n</blockquote>\n<h4 id=\"string类与stl的关系\"><a class=\"anchor\" href=\"#string类与stl的关系\">#</a> string 类与 STL 的关系</h4>\n<p>首先，我们要知道 string 并不属于严格意义上的 STL。在早期的 C++ 标准化过程中，string 类是 C++ 标准库中一个独立设计的类，设计初衷是提供比 C 语言中的 <code>char*</code>  更强大、灵活的字符串操作能力。STL 和 string 的发展是同时的，因此 STL 中并没有单独做一个 string，但是 STL 比 string 更早被标准化并引入 C++ 标准。</p>\n<h4 id=\"string类其实也是一个类模板\"><a class=\"anchor\" href=\"#string类其实也是一个类模板\">#</a> string 类其实也是一个类模板</h4>\n<p>C++ 中的 string 本质上是基于类模板的。虽然我们通常使用 string，但它实际上是 basic_string 类模板的一个特例化版本（ <code>std::basic_string&lt;char&gt;</code> ）。采用类模板主要是因为字符是有很多类型的，常见的是 ASCII 字符（char），但是还有宽字符（wchar_t）、Unicode 字符（char16_t、char32_t）等其他字符需要支持。</p>\n<h4 id=\"string类的迭代器iterator\"><a class=\"anchor\" href=\"#string类的迭代器iterator\">#</a> string 类的迭代器 iterator</h4>\n<p>迭代器是 C++ 标准库中用于遍历容器（如数组、向量、链表、字符串等）元素的对象。能够访问容器中的元素，同时还提供了灵活的接口来进行容器的遍历和操作。</p>\n<p>iterator 大概可以理解为一个作为容器（这里是 string）内部类的类似指针的东西。注意，不一定是指针，在不同编译器的实现下可能不同，而且部分容器无法用指针的方式作为迭代器。比方说，我使用 typeid 打印 string::iterator 的类型，得到的结果是：</p>\n<p><code>class std::_String_iterator&lt;class std::_String_val&lt;struct std::_Simple_types&lt;char&gt; &gt; &gt;</code></p>\n<p>这里 iterator 显然是一个类，而不是单纯的指针。</p>\n<p>这里演示一下 string 的迭代器的简单使用，其中涉及的部分接口将在下文介绍。</p>\n<figure class=\"highlight cpp\"><figcaption data-lang=\"C++\"></figcaption><table><tr><td data-num=\"1\"></td><td><pre><span class=\"token macro property\"><span class=\"token directive-hash\">#</span><span class=\"token directive keyword\">include</span> <span class=\"token string\">&lt;iostream></span></span></pre></td></tr><tr><td data-num=\"2\"></td><td><pre><span class=\"token macro property\"><span class=\"token directive-hash\">#</span><span class=\"token directive keyword\">include</span> <span class=\"token string\">&lt;string></span></span></pre></td></tr><tr><td data-num=\"3\"></td><td><pre></pre></td></tr><tr><td data-num=\"4\"></td><td><pre><span class=\"token keyword\">using</span> <span class=\"token keyword\">namespace</span> std<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"5\"></td><td><pre></pre></td></tr><tr><td data-num=\"6\"></td><td><pre><span class=\"token keyword\">int</span> <span class=\"token function\">main</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> </pre></td></tr><tr><td data-num=\"7\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"8\"></td><td><pre>    string str <span class=\"token operator\">=</span> <span class=\"token string\">\"Hello\"</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"9\"></td><td><pre></pre></td></tr><tr><td data-num=\"10\"></td><td><pre>    <span class=\"token comment\">//iterator 正向遍历</span></pre></td></tr><tr><td data-num=\"11\"></td><td><pre>    <span class=\"token keyword\">for</span> <span class=\"token punctuation\">(</span>string<span class=\"token double-colon punctuation\">::</span>iterator it <span class=\"token operator\">=</span> str<span class=\"token punctuation\">.</span><span class=\"token function\">begin</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span> it <span class=\"token operator\">!=</span> str<span class=\"token punctuation\">.</span><span class=\"token function\">end</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span> <span class=\"token operator\">++</span>it<span class=\"token punctuation\">)</span> </pre></td></tr><tr><td data-num=\"12\"></td><td><pre>    <span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"13\"></td><td><pre>        cout <span class=\"token operator\">&lt;&lt;</span> <span class=\"token operator\">*</span>it <span class=\"token operator\">&lt;&lt;</span> <span class=\"token char\">' '</span><span class=\"token punctuation\">;</span>  <span class=\"token comment\">// 输出: H e l l o</span></pre></td></tr><tr><td data-num=\"14\"></td><td><pre>    <span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"15\"></td><td><pre>    cout <span class=\"token operator\">&lt;&lt;</span> endl<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"16\"></td><td><pre></pre></td></tr><tr><td data-num=\"17\"></td><td><pre>    <span class=\"token comment\">// 使用 const_iterator 只读遍历</span></pre></td></tr><tr><td data-num=\"18\"></td><td><pre>    <span class=\"token keyword\">for</span> <span class=\"token punctuation\">(</span>string<span class=\"token double-colon punctuation\">::</span>const_iterator cit <span class=\"token operator\">=</span> str<span class=\"token punctuation\">.</span><span class=\"token function\">cbegin</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span> cit <span class=\"token operator\">!=</span> str<span class=\"token punctuation\">.</span><span class=\"token function\">cend</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span> <span class=\"token operator\">++</span>cit<span class=\"token punctuation\">)</span> </pre></td></tr><tr><td data-num=\"19\"></td><td><pre>    <span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"20\"></td><td><pre>        cout <span class=\"token operator\">&lt;&lt;</span> <span class=\"token operator\">*</span>cit <span class=\"token operator\">&lt;&lt;</span> <span class=\"token char\">' '</span><span class=\"token punctuation\">;</span>  <span class=\"token comment\">// 输出: H e l l o</span></pre></td></tr><tr><td data-num=\"21\"></td><td><pre>    <span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"22\"></td><td><pre>    cout <span class=\"token operator\">&lt;&lt;</span> endl<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"23\"></td><td><pre></pre></td></tr><tr><td data-num=\"24\"></td><td><pre>    <span class=\"token comment\">// 使用 reverse_iterator 反向遍历</span></pre></td></tr><tr><td data-num=\"25\"></td><td><pre>    <span class=\"token keyword\">for</span> <span class=\"token punctuation\">(</span>string<span class=\"token double-colon punctuation\">::</span>reverse_iterator rit <span class=\"token operator\">=</span> str<span class=\"token punctuation\">.</span><span class=\"token function\">rbegin</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span> rit <span class=\"token operator\">!=</span> str<span class=\"token punctuation\">.</span><span class=\"token function\">rend</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span> <span class=\"token operator\">++</span>rit<span class=\"token punctuation\">)</span> </pre></td></tr><tr><td data-num=\"26\"></td><td><pre>    <span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"27\"></td><td><pre>        cout <span class=\"token operator\">&lt;&lt;</span> <span class=\"token operator\">*</span>rit <span class=\"token operator\">&lt;&lt;</span> <span class=\"token char\">' '</span><span class=\"token punctuation\">;</span>  <span class=\"token comment\">// 输出: o l l e H</span></pre></td></tr><tr><td data-num=\"28\"></td><td><pre>    <span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"29\"></td><td><pre>    cout <span class=\"token operator\">&lt;&lt;</span> endl<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"30\"></td><td><pre></pre></td></tr><tr><td data-num=\"31\"></td><td><pre>    <span class=\"token keyword\">return</span> <span class=\"token number\">0</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"32\"></td><td><pre><span class=\"token punctuation\">&#125;</span></pre></td></tr></table></figure><h4 id=\"string类常用接口并不完全\"><a class=\"anchor\" href=\"#string类常用接口并不完全\">#</a> string 类常用接口（并不完全）</h4>\n<h5 id=\"string类常见构造\"><a class=\"anchor\" href=\"#string类常见构造\">#</a> string 类常见构造</h5>\n<table>\n<thead>\n<tr>\n<th>构造</th>\n<th>解释</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>string();</td>\n<td>构造一个长度为 0 的空字符串。</td>\n</tr>\n<tr>\n<td>string (const string&amp; str);</td>\n<td>拷贝构造一个字符串。</td>\n</tr>\n<tr>\n<td>string (const string&amp; str, size_t pos, size_t len = npos);</td>\n<td>从一个已有字符串的 pos 位置开始，选取长度为 len 的子字符序列来构造一个字符串。(npos 默认为 - 1，在 size_t 中即为 4294967295，也就是说如果省略第三个参数就是往后有多少拷多少)</td>\n</tr>\n<tr>\n<td>string (const char* s);</td>\n<td>C 语言字符串转为 string。</td>\n</tr>\n<tr>\n<td>string (const char* s, size_t n);</td>\n<td>从字符数组 s 中选前 n 个字符构造字符串。</td>\n</tr>\n<tr>\n<td>string (size_t n, char c);</td>\n<td>构造一个长度为 n，每一个字符都是 c 的字符串。</td>\n</tr>\n</tbody>\n</table>\n<figure class=\"highlight cpp\"><figcaption data-lang=\"C++\"></figcaption><table><tr><td data-num=\"1\"></td><td><pre><span class=\"token macro property\"><span class=\"token directive-hash\">#</span><span class=\"token directive keyword\">include</span> <span class=\"token string\">&lt;string></span></span></pre></td></tr><tr><td data-num=\"2\"></td><td><pre></pre></td></tr><tr><td data-num=\"3\"></td><td><pre><span class=\"token keyword\">using</span> <span class=\"token keyword\">namespace</span> std<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"4\"></td><td><pre></pre></td></tr><tr><td data-num=\"5\"></td><td><pre><span class=\"token keyword\">int</span> <span class=\"token function\">main</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"6\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"7\"></td><td><pre>\tstring s1 <span class=\"token operator\">=</span> <span class=\"token string\">\"Hello world!\"</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"8\"></td><td><pre>\tstring <span class=\"token function\">s2</span><span class=\"token punctuation\">(</span>s1<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"9\"></td><td><pre>\tstring <span class=\"token function\">s3</span><span class=\"token punctuation\">(</span>s1<span class=\"token punctuation\">,</span> <span class=\"token number\">5</span><span class=\"token punctuation\">,</span> <span class=\"token number\">5</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"10\"></td><td><pre>\tstring <span class=\"token function\">s4</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"Hello world!\"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"11\"></td><td><pre>\tstring <span class=\"token function\">s5</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"Hello world!\"</span><span class=\"token punctuation\">,</span> <span class=\"token number\">5</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"12\"></td><td><pre>\tstring <span class=\"token function\">s6</span><span class=\"token punctuation\">(</span><span class=\"token number\">10</span><span class=\"token punctuation\">,</span> <span class=\"token char\">'x'</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"13\"></td><td><pre></pre></td></tr><tr><td data-num=\"14\"></td><td><pre>\t<span class=\"token keyword\">return</span> <span class=\"token number\">0</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"15\"></td><td><pre><span class=\"token punctuation\">&#125;</span></pre></td></tr></table></figure><h5 id=\"string类常用容器操作\"><a class=\"anchor\" href=\"#string类常用容器操作\">#</a> string 类常用容器操作</h5>\n<h6 id=\"size与length\"><a class=\"anchor\" href=\"#size与length\">#</a> size 与 length</h6>\n<p><code>size_t size() const;</code></p>\n<p><code>size_t length() const;</code></p>\n<p>size 和 length 两个函数的作用和原理完全相同，size 用的更多。</p>\n<p>size 函数是为了与 STL 标准容器的接口保持一致而产生的，也更符合容器的抽象概念。但是 length 这个更符合自然语言的接口也被保留下来了，为了兼容性。</p>\n<figure class=\"highlight cpp\"><figcaption data-lang=\"C++\"></figcaption><table><tr><td data-num=\"1\"></td><td><pre><span class=\"token macro property\"><span class=\"token directive-hash\">#</span><span class=\"token directive keyword\">include</span> <span class=\"token string\">&lt;iostream></span></span></pre></td></tr><tr><td data-num=\"2\"></td><td><pre><span class=\"token macro property\"><span class=\"token directive-hash\">#</span><span class=\"token directive keyword\">include</span> <span class=\"token string\">&lt;string></span></span></pre></td></tr><tr><td data-num=\"3\"></td><td><pre></pre></td></tr><tr><td data-num=\"4\"></td><td><pre><span class=\"token keyword\">using</span> <span class=\"token keyword\">namespace</span> std<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"5\"></td><td><pre></pre></td></tr><tr><td data-num=\"6\"></td><td><pre><span class=\"token keyword\">int</span> <span class=\"token function\">main</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"7\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"8\"></td><td><pre>\tstring <span class=\"token function\">s</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"Hello, World!\"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"9\"></td><td><pre>\tcout <span class=\"token operator\">&lt;&lt;</span> s<span class=\"token punctuation\">.</span><span class=\"token function\">size</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">&lt;&lt;</span> endl<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"10\"></td><td><pre>\tcout <span class=\"token operator\">&lt;&lt;</span> s<span class=\"token punctuation\">.</span><span class=\"token function\">length</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">&lt;&lt;</span> endl<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"11\"></td><td><pre></pre></td></tr><tr><td data-num=\"12\"></td><td><pre>\t<span class=\"token keyword\">return</span> <span class=\"token number\">0</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"13\"></td><td><pre><span class=\"token punctuation\">&#125;</span></pre></td></tr></table></figure><h6 id=\"capacity\"><a class=\"anchor\" href=\"#capacity\">#</a> capacity</h6>\n<p><code>size_t capacity() const;</code></p>\n<p>capacity 函数返回字符串的容量。</p>\n<p>注意：<strong>string 会默认为字符串预先分配一段最小的初始容量</strong>，这个容量可以根据编译器实现不同而有所不同。而当容量超出先前的容量时，就会<strong>以顺序表的方式进行容量扩展，而不是精准到每一个字节扩展</strong>。（可见数据结构笔记 #1）</p>\n<p>比方说下面的程序在我的环境下运行输出为：15、15、15、31。</p>\n<figure class=\"highlight cpp\"><figcaption data-lang=\"C++\"></figcaption><table><tr><td data-num=\"1\"></td><td><pre><span class=\"token macro property\"><span class=\"token directive-hash\">#</span><span class=\"token directive keyword\">include</span> <span class=\"token string\">&lt;iostream></span></span></pre></td></tr><tr><td data-num=\"2\"></td><td><pre><span class=\"token macro property\"><span class=\"token directive-hash\">#</span><span class=\"token directive keyword\">include</span> <span class=\"token string\">&lt;string></span></span></pre></td></tr><tr><td data-num=\"3\"></td><td><pre></pre></td></tr><tr><td data-num=\"4\"></td><td><pre><span class=\"token keyword\">using</span> <span class=\"token keyword\">namespace</span> std<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"5\"></td><td><pre></pre></td></tr><tr><td data-num=\"6\"></td><td><pre><span class=\"token keyword\">int</span> <span class=\"token function\">main</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"7\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"8\"></td><td><pre>\tstring str1<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"9\"></td><td><pre>\tcout <span class=\"token operator\">&lt;&lt;</span> str1<span class=\"token punctuation\">.</span><span class=\"token function\">capacity</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">&lt;&lt;</span> endl<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"10\"></td><td><pre></pre></td></tr><tr><td data-num=\"11\"></td><td><pre>\tstring str2 <span class=\"token operator\">=</span> <span class=\"token string\">\"Hello, World!\"</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"12\"></td><td><pre>\tcout <span class=\"token operator\">&lt;&lt;</span> str2<span class=\"token punctuation\">.</span><span class=\"token function\">capacity</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">&lt;&lt;</span> endl<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"13\"></td><td><pre></pre></td></tr><tr><td data-num=\"14\"></td><td><pre>\tstring str3 <span class=\"token operator\">=</span> <span class=\"token string\">\"123456789012345\"</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"15\"></td><td><pre>\tcout <span class=\"token operator\">&lt;&lt;</span> str3<span class=\"token punctuation\">.</span><span class=\"token function\">capacity</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">&lt;&lt;</span> endl<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"16\"></td><td><pre></pre></td></tr><tr><td data-num=\"17\"></td><td><pre>\tstring str4 <span class=\"token operator\">=</span> <span class=\"token string\">\"1234567890123456\"</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"18\"></td><td><pre>\tcout <span class=\"token operator\">&lt;&lt;</span> str4<span class=\"token punctuation\">.</span><span class=\"token function\">capacity</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">&lt;&lt;</span> endl<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"19\"></td><td><pre></pre></td></tr><tr><td data-num=\"20\"></td><td><pre>\t<span class=\"token keyword\">return</span> <span class=\"token number\">0</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"21\"></td><td><pre><span class=\"token punctuation\">&#125;</span></pre></td></tr></table></figure><h6 id=\"empty\"><a class=\"anchor\" href=\"#empty\">#</a> empty</h6>\n<p><code>bool enpty() const;</code></p>\n<p>检测字符串是否为空串，如果是返回 true，如果否返回 false。</p>\n<figure class=\"highlight cpp\"><figcaption data-lang=\"C++\"></figcaption><table><tr><td data-num=\"1\"></td><td><pre><span class=\"token macro property\"><span class=\"token directive-hash\">#</span><span class=\"token directive keyword\">include</span> <span class=\"token string\">&lt;iostream></span></span></pre></td></tr><tr><td data-num=\"2\"></td><td><pre></pre></td></tr><tr><td data-num=\"3\"></td><td><pre><span class=\"token keyword\">using</span> <span class=\"token keyword\">namespace</span> std<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"4\"></td><td><pre></pre></td></tr><tr><td data-num=\"5\"></td><td><pre><span class=\"token keyword\">int</span> <span class=\"token function\">main</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"6\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"7\"></td><td><pre>\tstring s1 <span class=\"token operator\">=</span> <span class=\"token string\">\"a\"</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"8\"></td><td><pre>\tcout <span class=\"token operator\">&lt;&lt;</span> s1<span class=\"token punctuation\">.</span><span class=\"token function\">empty</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">&lt;&lt;</span> endl<span class=\"token punctuation\">;</span>\t<span class=\"token comment\">//0</span></pre></td></tr><tr><td data-num=\"9\"></td><td><pre></pre></td></tr><tr><td data-num=\"10\"></td><td><pre>\tstring s2 <span class=\"token operator\">=</span> <span class=\"token string\">\"\"</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"11\"></td><td><pre>\tcout <span class=\"token operator\">&lt;&lt;</span> s2<span class=\"token punctuation\">.</span><span class=\"token function\">empty</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">&lt;&lt;</span> endl<span class=\"token punctuation\">;</span>\t<span class=\"token comment\">//1</span></pre></td></tr><tr><td data-num=\"12\"></td><td><pre></pre></td></tr><tr><td data-num=\"13\"></td><td><pre>\tstring s3<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"14\"></td><td><pre>\tcout <span class=\"token operator\">&lt;&lt;</span> s3<span class=\"token punctuation\">.</span><span class=\"token function\">empty</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">&lt;&lt;</span> endl<span class=\"token punctuation\">;</span>\t<span class=\"token comment\">//1</span></pre></td></tr><tr><td data-num=\"15\"></td><td><pre></pre></td></tr><tr><td data-num=\"16\"></td><td><pre>\t<span class=\"token keyword\">return</span> <span class=\"token number\">0</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"17\"></td><td><pre><span class=\"token punctuation\">&#125;</span></pre></td></tr></table></figure><h6 id=\"clear\"><a class=\"anchor\" href=\"#clear\">#</a> clear</h6>\n<p><code>void clear();</code></p>\n<p>clear 函数将 string 中的有效字符清空，但是不会改变底层空间的大小。</p>\n<figure class=\"highlight cpp\"><figcaption data-lang=\"C++\"></figcaption><table><tr><td data-num=\"1\"></td><td><pre><span class=\"token macro property\"><span class=\"token directive-hash\">#</span><span class=\"token directive keyword\">include</span> <span class=\"token string\">&lt;iostream></span></span></pre></td></tr><tr><td data-num=\"2\"></td><td><pre></pre></td></tr><tr><td data-num=\"3\"></td><td><pre><span class=\"token keyword\">using</span> <span class=\"token keyword\">namespace</span> std<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"4\"></td><td><pre></pre></td></tr><tr><td data-num=\"5\"></td><td><pre><span class=\"token keyword\">int</span> <span class=\"token function\">main</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"6\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"7\"></td><td><pre>\tstring s <span class=\"token operator\">=</span> <span class=\"token string\">\"a\"</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"8\"></td><td><pre>\tcout <span class=\"token operator\">&lt;&lt;</span> s<span class=\"token punctuation\">.</span><span class=\"token function\">size</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">&lt;&lt;</span> endl<span class=\"token punctuation\">;</span>\t<span class=\"token comment\">//1</span></pre></td></tr><tr><td data-num=\"9\"></td><td><pre>\tcout <span class=\"token operator\">&lt;&lt;</span> s<span class=\"token punctuation\">.</span><span class=\"token function\">capacity</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">&lt;&lt;</span> endl<span class=\"token punctuation\">;</span>\t<span class=\"token comment\">//15</span></pre></td></tr><tr><td data-num=\"10\"></td><td><pre></pre></td></tr><tr><td data-num=\"11\"></td><td><pre>\ts<span class=\"token punctuation\">.</span><span class=\"token function\">clear</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"12\"></td><td><pre>\tcout <span class=\"token operator\">&lt;&lt;</span> s<span class=\"token punctuation\">.</span><span class=\"token function\">size</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">&lt;&lt;</span> endl<span class=\"token punctuation\">;</span>\t<span class=\"token comment\">//0</span></pre></td></tr><tr><td data-num=\"13\"></td><td><pre>\tcout <span class=\"token operator\">&lt;&lt;</span> s<span class=\"token punctuation\">.</span><span class=\"token function\">capacity</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">&lt;&lt;</span> endl<span class=\"token punctuation\">;</span>\t<span class=\"token comment\">//15</span></pre></td></tr><tr><td data-num=\"14\"></td><td><pre>\tcout <span class=\"token operator\">&lt;&lt;</span> s <span class=\"token operator\">&lt;&lt;</span> endl<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"15\"></td><td><pre><span class=\"token punctuation\">&#125;</span></pre></td></tr></table></figure><h6 id=\"reserve\"><a class=\"anchor\" href=\"#reserve\">#</a> reserve</h6>\n<p><code>void reserve(size_t n=0);</code></p>\n<p>reserve 函数为字符串预留空间，但是不改变有效元素个数。也就是说，reserve 会改变 capacity，但是不会影响 size。另外，reserve 的参数小于 string 底层空间总大小时，不会进行改变。</p>\n<p>注意，reserve 并不是将 capacity 改成其参数 n 的大小。而是继续以顺序表扩容的方式增大其容量以至于足以容纳这么多空间。比方说：</p>\n<figure class=\"highlight cpp\"><figcaption data-lang=\"C++\"></figcaption><table><tr><td data-num=\"1\"></td><td><pre><span class=\"token macro property\"><span class=\"token directive-hash\">#</span><span class=\"token directive keyword\">include</span> <span class=\"token string\">&lt;iostream></span></span></pre></td></tr><tr><td data-num=\"2\"></td><td><pre><span class=\"token macro property\"><span class=\"token directive-hash\">#</span><span class=\"token directive keyword\">include</span> <span class=\"token string\">&lt;string></span></span></pre></td></tr><tr><td data-num=\"3\"></td><td><pre></pre></td></tr><tr><td data-num=\"4\"></td><td><pre><span class=\"token keyword\">using</span> <span class=\"token keyword\">namespace</span> std<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"5\"></td><td><pre></pre></td></tr><tr><td data-num=\"6\"></td><td><pre><span class=\"token keyword\">int</span> <span class=\"token function\">main</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"7\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"8\"></td><td><pre>\tstring <span class=\"token function\">s</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"Hello world!\"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"9\"></td><td><pre>\tcout <span class=\"token operator\">&lt;&lt;</span> s<span class=\"token punctuation\">.</span><span class=\"token function\">capacity</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">&lt;&lt;</span> endl<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"10\"></td><td><pre>\ts<span class=\"token punctuation\">.</span><span class=\"token function\">reserve</span><span class=\"token punctuation\">(</span><span class=\"token number\">5</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"11\"></td><td><pre>\tcout <span class=\"token operator\">&lt;&lt;</span> s<span class=\"token punctuation\">.</span><span class=\"token function\">capacity</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">&lt;&lt;</span> endl<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"12\"></td><td><pre>\ts<span class=\"token punctuation\">.</span><span class=\"token function\">reserve</span><span class=\"token punctuation\">(</span><span class=\"token number\">111</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"13\"></td><td><pre>\tcout <span class=\"token operator\">&lt;&lt;</span> s<span class=\"token punctuation\">.</span><span class=\"token function\">capacity</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">&lt;&lt;</span> endl<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"14\"></td><td><pre>\ts<span class=\"token punctuation\">.</span><span class=\"token function\">reserve</span><span class=\"token punctuation\">(</span><span class=\"token number\">112</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"15\"></td><td><pre>\tcout <span class=\"token operator\">&lt;&lt;</span> s<span class=\"token punctuation\">.</span><span class=\"token function\">capacity</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">&lt;&lt;</span> endl<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"16\"></td><td><pre></pre></td></tr><tr><td data-num=\"17\"></td><td><pre>\t<span class=\"token keyword\">return</span> <span class=\"token number\">0</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"18\"></td><td><pre><span class=\"token punctuation\">&#125;</span></pre></td></tr></table></figure><p>该程序在我的环境下的输出为：</p>\n<figure class=\"highlight bash\"><figcaption data-lang=\"bash\"></figcaption><table><tr><td data-num=\"1\"></td><td><pre><span class=\"token number\">15</span></pre></td></tr><tr><td data-num=\"2\"></td><td><pre><span class=\"token number\">15</span></pre></td></tr><tr><td data-num=\"3\"></td><td><pre><span class=\"token number\">111</span></pre></td></tr><tr><td data-num=\"4\"></td><td><pre><span class=\"token number\">166</span></pre></td></tr></table></figure><h6 id=\"resize\"><a class=\"anchor\" href=\"#resize\">#</a> resize</h6>\n<figure class=\"highlight cpp\"><figcaption data-lang=\"C++\"></figcaption><table><tr><td data-num=\"1\"></td><td><pre><span class=\"token keyword\">void</span> <span class=\"token function\">resize</span> <span class=\"token punctuation\">(</span>size_t n<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"2\"></td><td><pre><span class=\"token keyword\">void</span> <span class=\"token function\">resize</span> <span class=\"token punctuation\">(</span>size_t n<span class=\"token punctuation\">,</span> <span class=\"token keyword\">char</span> c<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr></table></figure><p>resize 函数用于改变字符串的有效内容的大小。</p>\n<ol>\n<li>当 n 比原先的 size 小：字符串将被截断到指定的大小。</li>\n<li>当 n 比原先的 size 大：扩大字符串，用给定的字符 c 来填充扩展部分。如果没有给定 c，则使用 <code>\\0</code>  来填充。</li>\n</ol>\n<figure class=\"highlight cpp\"><figcaption data-lang=\"C++\"></figcaption><table><tr><td data-num=\"1\"></td><td><pre><span class=\"token macro property\"><span class=\"token directive-hash\">#</span><span class=\"token directive keyword\">include</span> <span class=\"token string\">&lt;iostream></span></span></pre></td></tr><tr><td data-num=\"2\"></td><td><pre><span class=\"token macro property\"><span class=\"token directive-hash\">#</span><span class=\"token directive keyword\">include</span> <span class=\"token string\">&lt;string></span></span></pre></td></tr><tr><td data-num=\"3\"></td><td><pre></pre></td></tr><tr><td data-num=\"4\"></td><td><pre><span class=\"token keyword\">using</span> <span class=\"token keyword\">namespace</span> std<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"5\"></td><td><pre></pre></td></tr><tr><td data-num=\"6\"></td><td><pre><span class=\"token keyword\">int</span> <span class=\"token function\">main</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"7\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"8\"></td><td><pre>\tstring s <span class=\"token operator\">=</span> <span class=\"token string\">\"Hello\"</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"9\"></td><td><pre>\tcout <span class=\"token operator\">&lt;&lt;</span> <span class=\"token string\">\"s = \"</span> <span class=\"token operator\">&lt;&lt;</span> s <span class=\"token operator\">&lt;&lt;</span> endl<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"10\"></td><td><pre>\tcout <span class=\"token operator\">&lt;&lt;</span> <span class=\"token string\">\"s.size() = \"</span> <span class=\"token operator\">&lt;&lt;</span> s<span class=\"token punctuation\">.</span><span class=\"token function\">size</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">&lt;&lt;</span> endl<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"11\"></td><td><pre></pre></td></tr><tr><td data-num=\"12\"></td><td><pre>\ts<span class=\"token punctuation\">.</span><span class=\"token function\">resize</span><span class=\"token punctuation\">(</span><span class=\"token number\">4</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"13\"></td><td><pre>\tcout <span class=\"token operator\">&lt;&lt;</span> <span class=\"token string\">\"s = \"</span> <span class=\"token operator\">&lt;&lt;</span> s <span class=\"token operator\">&lt;&lt;</span> endl<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"14\"></td><td><pre>\tcout <span class=\"token operator\">&lt;&lt;</span> <span class=\"token string\">\"s.size() = \"</span> <span class=\"token operator\">&lt;&lt;</span> s<span class=\"token punctuation\">.</span><span class=\"token function\">size</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">&lt;&lt;</span> endl<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"15\"></td><td><pre></pre></td></tr><tr><td data-num=\"16\"></td><td><pre>\ts<span class=\"token punctuation\">.</span><span class=\"token function\">resize</span><span class=\"token punctuation\">(</span><span class=\"token number\">6</span><span class=\"token punctuation\">,</span> <span class=\"token char\">'!'</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"17\"></td><td><pre>\tcout <span class=\"token operator\">&lt;&lt;</span> <span class=\"token string\">\"s = \"</span> <span class=\"token operator\">&lt;&lt;</span> s <span class=\"token operator\">&lt;&lt;</span> endl<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"18\"></td><td><pre>\tcout <span class=\"token operator\">&lt;&lt;</span> <span class=\"token string\">\"s.size() = \"</span> <span class=\"token operator\">&lt;&lt;</span> s<span class=\"token punctuation\">.</span><span class=\"token function\">size</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">&lt;&lt;</span> endl<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"19\"></td><td><pre></pre></td></tr><tr><td data-num=\"20\"></td><td><pre>\ts<span class=\"token punctuation\">.</span><span class=\"token function\">resize</span><span class=\"token punctuation\">(</span><span class=\"token number\">10</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"21\"></td><td><pre>\tcout <span class=\"token operator\">&lt;&lt;</span> <span class=\"token string\">\"s = \"</span> <span class=\"token operator\">&lt;&lt;</span> s <span class=\"token operator\">&lt;&lt;</span> endl<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"22\"></td><td><pre>\tcout <span class=\"token operator\">&lt;&lt;</span> <span class=\"token string\">\"s.size() = \"</span> <span class=\"token operator\">&lt;&lt;</span> s<span class=\"token punctuation\">.</span><span class=\"token function\">size</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">&lt;&lt;</span> endl<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"23\"></td><td><pre></pre></td></tr><tr><td data-num=\"24\"></td><td><pre>\ts<span class=\"token punctuation\">.</span><span class=\"token function\">resize</span><span class=\"token punctuation\">(</span><span class=\"token number\">12</span><span class=\"token punctuation\">,</span> <span class=\"token char\">'?'</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"25\"></td><td><pre>\tcout <span class=\"token operator\">&lt;&lt;</span> <span class=\"token string\">\"s = \"</span> <span class=\"token operator\">&lt;&lt;</span> s <span class=\"token operator\">&lt;&lt;</span> endl<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"26\"></td><td><pre>\tcout <span class=\"token operator\">&lt;&lt;</span> <span class=\"token string\">\"s.size() = \"</span> <span class=\"token operator\">&lt;&lt;</span> s<span class=\"token punctuation\">.</span><span class=\"token function\">size</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">&lt;&lt;</span> endl<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"27\"></td><td><pre></pre></td></tr><tr><td data-num=\"28\"></td><td><pre>\t<span class=\"token keyword\">return</span> <span class=\"token number\">0</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"29\"></td><td><pre><span class=\"token punctuation\">&#125;</span></pre></td></tr></table></figure><p>上述程序输出为：</p>\n<figure class=\"highlight bash\"><figcaption data-lang=\"bash\"></figcaption><table><tr><td data-num=\"1\"></td><td><pre>s <span class=\"token operator\">=</span> Hello</pre></td></tr><tr><td data-num=\"2\"></td><td><pre>s.size<span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=</span> <span class=\"token number\">5</span></pre></td></tr><tr><td data-num=\"3\"></td><td><pre>s <span class=\"token operator\">=</span> Hell</pre></td></tr><tr><td data-num=\"4\"></td><td><pre>s.size<span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=</span> <span class=\"token number\">4</span></pre></td></tr><tr><td data-num=\"5\"></td><td><pre>s <span class=\"token operator\">=</span> Hell<span class=\"token operator\">!</span><span class=\"token operator\">!</span></pre></td></tr><tr><td data-num=\"6\"></td><td><pre>s.size<span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=</span> <span class=\"token number\">6</span></pre></td></tr><tr><td data-num=\"7\"></td><td><pre>s <span class=\"token operator\">=</span> Hell<span class=\"token operator\">!</span><span class=\"token operator\">!</span></pre></td></tr><tr><td data-num=\"8\"></td><td><pre>s.size<span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=</span> <span class=\"token number\">10</span></pre></td></tr><tr><td data-num=\"9\"></td><td><pre>s <span class=\"token operator\">=</span> Hell<span class=\"token operator\">!</span><span class=\"token operator\">!</span>??</pre></td></tr><tr><td data-num=\"10\"></td><td><pre>s.size<span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=</span> <span class=\"token number\">12</span></pre></td></tr></table></figure><p>注意，这里 <code>!!</code>  和 <code>??</code>  之间是存在 4 个 <code>\\0</code>  的，只是不会被打印出来。但实际上我们检视内存就能看到：</p>\n<p><img data-src=\"1.png\" alt=\"内存\" /></p>\n<h5 id=\"string类对象的访问和遍历操作\"><a class=\"anchor\" href=\"#string类对象的访问和遍历操作\">#</a> string 类对象的访问和遍历操作</h5>\n<h6 id=\"operator\"><a class=\"anchor\" href=\"#operator\">#</a> operator[]</h6>\n<h6 id=\"char-operator-size_t-pos\"><a class=\"anchor\" href=\"#char-operator-size_t-pos\">#</a>  <code>char&amp; operator[] (size_t pos);</code></h6>\n<h6 id=\"const-char-operator-size_t-pos-const\"><a class=\"anchor\" href=\"#const-char-operator-size_t-pos-const\">#</a>  <code>const char&amp; operator[] (size_t pos) const;</code></h6>\n<p>与数组的访问操作符类似，返回 pos 位置的字符。如果 pos 等于字符串的有效字符数，也能返回对一个 <code>\\0</code>  的引用。</p>\n<figure class=\"highlight cpp\"><figcaption data-lang=\"C++\"></figcaption><table><tr><td data-num=\"1\"></td><td><pre><span class=\"token macro property\"><span class=\"token directive-hash\">#</span><span class=\"token directive keyword\">include</span> <span class=\"token string\">&lt;iostream></span></span></pre></td></tr><tr><td data-num=\"2\"></td><td><pre><span class=\"token macro property\"><span class=\"token directive-hash\">#</span><span class=\"token directive keyword\">include</span> <span class=\"token string\">&lt;string></span></span></pre></td></tr><tr><td data-num=\"3\"></td><td><pre></pre></td></tr><tr><td data-num=\"4\"></td><td><pre><span class=\"token keyword\">using</span> <span class=\"token keyword\">namespace</span> std<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"5\"></td><td><pre></pre></td></tr><tr><td data-num=\"6\"></td><td><pre><span class=\"token keyword\">int</span> <span class=\"token function\">main</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"7\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"8\"></td><td><pre>\tstring str <span class=\"token operator\">=</span> <span class=\"token string\">\"Hello\"</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"9\"></td><td><pre>\t<span class=\"token keyword\">for</span> <span class=\"token punctuation\">(</span><span class=\"token keyword\">int</span> i <span class=\"token operator\">=</span> <span class=\"token number\">0</span><span class=\"token punctuation\">;</span> i <span class=\"token operator\">&lt;</span> str<span class=\"token punctuation\">.</span><span class=\"token function\">size</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span> i<span class=\"token operator\">++</span><span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"10\"></td><td><pre>\t<span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"11\"></td><td><pre>\t\tcout <span class=\"token operator\">&lt;&lt;</span> str<span class=\"token punctuation\">[</span>i<span class=\"token punctuation\">]</span> <span class=\"token operator\">&lt;&lt;</span> endl<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"12\"></td><td><pre>\t<span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"13\"></td><td><pre></pre></td></tr><tr><td data-num=\"14\"></td><td><pre>\tstr<span class=\"token punctuation\">[</span><span class=\"token number\">0</span><span class=\"token punctuation\">]</span> <span class=\"token operator\">=</span> <span class=\"token char\">'h'</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"15\"></td><td><pre>\t<span class=\"token keyword\">for</span> <span class=\"token punctuation\">(</span><span class=\"token keyword\">int</span> i <span class=\"token operator\">=</span> <span class=\"token number\">0</span><span class=\"token punctuation\">;</span> i <span class=\"token operator\">&lt;</span> str<span class=\"token punctuation\">.</span><span class=\"token function\">size</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span> i<span class=\"token operator\">++</span><span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"16\"></td><td><pre>\t<span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"17\"></td><td><pre>\t\tcout <span class=\"token operator\">&lt;&lt;</span> str<span class=\"token punctuation\">[</span>i<span class=\"token punctuation\">]</span> <span class=\"token operator\">&lt;&lt;</span> endl<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"18\"></td><td><pre>\t<span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"19\"></td><td><pre></pre></td></tr><tr><td data-num=\"20\"></td><td><pre>\t<span class=\"token keyword\">return</span> <span class=\"token number\">0</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"21\"></td><td><pre><span class=\"token punctuation\">&#125;</span></pre></td></tr></table></figure><h6 id=\"begin与end包括r系与c系\"><a class=\"anchor\" href=\"#begin与end包括r系与c系\">#</a> begin 与 end (包括 r 系与 c 系)</h6>\n<p><code>iterator begin();</code></p>\n<p><code>iterator end();</code></p>\n<p>begin 和 end 函数返回指向字符串<strong>起始位置</strong>和<strong>结束位置下一位置</strong>的迭代器。cbegin 和 cend 返回的则是常迭代器，rbegin 和 rend 返回反向迭代器，crbegin 和 crend 自然就是反向常迭代器。</p>\n<figure class=\"highlight cpp\"><figcaption data-lang=\"C++\"></figcaption><table><tr><td data-num=\"1\"></td><td><pre><span class=\"token macro property\"><span class=\"token directive-hash\">#</span><span class=\"token directive keyword\">include</span> <span class=\"token string\">&lt;iostream></span></span></pre></td></tr><tr><td data-num=\"2\"></td><td><pre><span class=\"token macro property\"><span class=\"token directive-hash\">#</span><span class=\"token directive keyword\">include</span> <span class=\"token string\">&lt;string></span></span></pre></td></tr><tr><td data-num=\"3\"></td><td><pre></pre></td></tr><tr><td data-num=\"4\"></td><td><pre><span class=\"token keyword\">using</span> <span class=\"token keyword\">namespace</span> std<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"5\"></td><td><pre></pre></td></tr><tr><td data-num=\"6\"></td><td><pre><span class=\"token keyword\">int</span> <span class=\"token function\">main</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> </pre></td></tr><tr><td data-num=\"7\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"8\"></td><td><pre>    string str <span class=\"token operator\">=</span> <span class=\"token string\">\"Hello\"</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"9\"></td><td><pre></pre></td></tr><tr><td data-num=\"10\"></td><td><pre>    <span class=\"token comment\">//iterator 正向遍历</span></pre></td></tr><tr><td data-num=\"11\"></td><td><pre>    <span class=\"token keyword\">for</span> <span class=\"token punctuation\">(</span>string<span class=\"token double-colon punctuation\">::</span>iterator it <span class=\"token operator\">=</span> str<span class=\"token punctuation\">.</span><span class=\"token function\">begin</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span> it <span class=\"token operator\">!=</span> str<span class=\"token punctuation\">.</span><span class=\"token function\">end</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span> <span class=\"token operator\">++</span>it<span class=\"token punctuation\">)</span> </pre></td></tr><tr><td data-num=\"12\"></td><td><pre>    <span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"13\"></td><td><pre>        cout <span class=\"token operator\">&lt;&lt;</span> <span class=\"token operator\">*</span>it <span class=\"token operator\">&lt;&lt;</span> <span class=\"token char\">' '</span><span class=\"token punctuation\">;</span>  <span class=\"token comment\">// 输出: H e l l o</span></pre></td></tr><tr><td data-num=\"14\"></td><td><pre>    <span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"15\"></td><td><pre>    cout <span class=\"token operator\">&lt;&lt;</span> endl<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"16\"></td><td><pre></pre></td></tr><tr><td data-num=\"17\"></td><td><pre>    <span class=\"token comment\">// 使用 const_iterator 只读遍历</span></pre></td></tr><tr><td data-num=\"18\"></td><td><pre>    <span class=\"token keyword\">for</span> <span class=\"token punctuation\">(</span>string<span class=\"token double-colon punctuation\">::</span>const_iterator cit <span class=\"token operator\">=</span> str<span class=\"token punctuation\">.</span><span class=\"token function\">cbegin</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span> cit <span class=\"token operator\">!=</span> str<span class=\"token punctuation\">.</span><span class=\"token function\">cend</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span> <span class=\"token operator\">++</span>cit<span class=\"token punctuation\">)</span> </pre></td></tr><tr><td data-num=\"19\"></td><td><pre>    <span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"20\"></td><td><pre>        cout <span class=\"token operator\">&lt;&lt;</span> <span class=\"token operator\">*</span>cit <span class=\"token operator\">&lt;&lt;</span> <span class=\"token char\">' '</span><span class=\"token punctuation\">;</span>  <span class=\"token comment\">// 输出: H e l l o</span></pre></td></tr><tr><td data-num=\"21\"></td><td><pre>    <span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"22\"></td><td><pre>    cout <span class=\"token operator\">&lt;&lt;</span> endl<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"23\"></td><td><pre></pre></td></tr><tr><td data-num=\"24\"></td><td><pre>    <span class=\"token comment\">// 使用 reverse_iterator 反向遍历</span></pre></td></tr><tr><td data-num=\"25\"></td><td><pre>    <span class=\"token keyword\">for</span> <span class=\"token punctuation\">(</span>string<span class=\"token double-colon punctuation\">::</span>reverse_iterator rit <span class=\"token operator\">=</span> str<span class=\"token punctuation\">.</span><span class=\"token function\">rbegin</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span> rit <span class=\"token operator\">!=</span> str<span class=\"token punctuation\">.</span><span class=\"token function\">rend</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span> <span class=\"token operator\">++</span>rit<span class=\"token punctuation\">)</span> </pre></td></tr><tr><td data-num=\"26\"></td><td><pre>    <span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"27\"></td><td><pre>        cout <span class=\"token operator\">&lt;&lt;</span> <span class=\"token operator\">*</span>rit <span class=\"token operator\">&lt;&lt;</span> <span class=\"token char\">' '</span><span class=\"token punctuation\">;</span>  <span class=\"token comment\">// 输出: o l l e H</span></pre></td></tr><tr><td data-num=\"28\"></td><td><pre>    <span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"29\"></td><td><pre>    cout <span class=\"token operator\">&lt;&lt;</span> endl<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"30\"></td><td><pre></pre></td></tr><tr><td data-num=\"31\"></td><td><pre>    <span class=\"token keyword\">return</span> <span class=\"token number\">0</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"32\"></td><td><pre><span class=\"token punctuation\">&#125;</span></pre></td></tr></table></figure><h6 id=\"范围forc11\"><a class=\"anchor\" href=\"#范围forc11\">#</a> 范围 for (C++11)</h6>\n<p>C++11 支持的范围 for 也可以用来遍历 string 类对象。</p>\n<figure class=\"highlight cpp\"><figcaption data-lang=\"C++\"></figcaption><table><tr><td data-num=\"1\"></td><td><pre><span class=\"token macro property\"><span class=\"token directive-hash\">#</span><span class=\"token directive keyword\">include</span> <span class=\"token string\">&lt;iostream></span></span></pre></td></tr><tr><td data-num=\"2\"></td><td><pre><span class=\"token macro property\"><span class=\"token directive-hash\">#</span><span class=\"token directive keyword\">include</span> <span class=\"token string\">&lt;string></span></span></pre></td></tr><tr><td data-num=\"3\"></td><td><pre></pre></td></tr><tr><td data-num=\"4\"></td><td><pre><span class=\"token keyword\">using</span> <span class=\"token keyword\">namespace</span> std<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"5\"></td><td><pre></pre></td></tr><tr><td data-num=\"6\"></td><td><pre><span class=\"token keyword\">int</span> <span class=\"token function\">main</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"7\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"8\"></td><td><pre>\tstring str <span class=\"token operator\">=</span> <span class=\"token string\">\"Hello, World!\"</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"9\"></td><td><pre>\t<span class=\"token keyword\">for</span> <span class=\"token punctuation\">(</span><span class=\"token keyword\">auto</span><span class=\"token operator\">&amp;</span> c <span class=\"token operator\">:</span> str<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"10\"></td><td><pre>\t<span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"11\"></td><td><pre>\t\tcout <span class=\"token operator\">&lt;&lt;</span> c <span class=\"token operator\">&lt;&lt;</span> endl<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"12\"></td><td><pre>\t<span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"13\"></td><td><pre></pre></td></tr><tr><td data-num=\"14\"></td><td><pre>\t<span class=\"token keyword\">return</span> <span class=\"token number\">0</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"15\"></td><td><pre><span class=\"token punctuation\">&#125;</span></pre></td></tr></table></figure><h5 id=\"string类对象的修改操作\"><a class=\"anchor\" href=\"#string类对象的修改操作\">#</a> string 类对象的修改操作</h5>\n<h6 id=\"push_back\"><a class=\"anchor\" href=\"#push_back\">#</a> push_back</h6>\n<p><code>void push_back (char c);</code></p>\n<p>push_back 在字符串后尾插字符 c。</p>\n<figure class=\"highlight cpp\"><figcaption data-lang=\"C++\"></figcaption><table><tr><td data-num=\"1\"></td><td><pre><span class=\"token macro property\"><span class=\"token directive-hash\">#</span><span class=\"token directive keyword\">include</span> <span class=\"token string\">&lt;iostream></span></span></pre></td></tr><tr><td data-num=\"2\"></td><td><pre><span class=\"token macro property\"><span class=\"token directive-hash\">#</span><span class=\"token directive keyword\">include</span> <span class=\"token string\">&lt;string></span></span></pre></td></tr><tr><td data-num=\"3\"></td><td><pre></pre></td></tr><tr><td data-num=\"4\"></td><td><pre><span class=\"token keyword\">using</span> <span class=\"token keyword\">namespace</span> std<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"5\"></td><td><pre></pre></td></tr><tr><td data-num=\"6\"></td><td><pre><span class=\"token keyword\">int</span> <span class=\"token function\">main</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"7\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"8\"></td><td><pre>\tstring str <span class=\"token operator\">=</span> <span class=\"token string\">\"Hello\"</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"9\"></td><td><pre>\tcout <span class=\"token operator\">&lt;&lt;</span> <span class=\"token string\">\"str: \"</span> <span class=\"token operator\">&lt;&lt;</span> str <span class=\"token operator\">&lt;&lt;</span> endl<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"10\"></td><td><pre></pre></td></tr><tr><td data-num=\"11\"></td><td><pre>\tstr<span class=\"token punctuation\">.</span><span class=\"token function\">push_back</span><span class=\"token punctuation\">(</span><span class=\"token char\">' '</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"12\"></td><td><pre>\tcout <span class=\"token operator\">&lt;&lt;</span> <span class=\"token string\">\"str: \"</span> <span class=\"token operator\">&lt;&lt;</span> str <span class=\"token operator\">&lt;&lt;</span> endl<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"13\"></td><td><pre></pre></td></tr><tr><td data-num=\"14\"></td><td><pre>\tstr<span class=\"token punctuation\">.</span><span class=\"token function\">push_back</span><span class=\"token punctuation\">(</span><span class=\"token char\">'W'</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"15\"></td><td><pre>\tcout <span class=\"token operator\">&lt;&lt;</span> <span class=\"token string\">\"str: \"</span> <span class=\"token operator\">&lt;&lt;</span> str <span class=\"token operator\">&lt;&lt;</span> endl<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"16\"></td><td><pre></pre></td></tr><tr><td data-num=\"17\"></td><td><pre>\tstr<span class=\"token punctuation\">.</span><span class=\"token function\">push_back</span><span class=\"token punctuation\">(</span><span class=\"token char\">'o'</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"18\"></td><td><pre>\tcout <span class=\"token operator\">&lt;&lt;</span> <span class=\"token string\">\"str: \"</span> <span class=\"token operator\">&lt;&lt;</span> str <span class=\"token operator\">&lt;&lt;</span> endl<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"19\"></td><td><pre></pre></td></tr><tr><td data-num=\"20\"></td><td><pre>\tstr<span class=\"token punctuation\">.</span><span class=\"token function\">push_back</span><span class=\"token punctuation\">(</span><span class=\"token char\">'r'</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"21\"></td><td><pre>\tcout <span class=\"token operator\">&lt;&lt;</span> <span class=\"token string\">\"str: \"</span> <span class=\"token operator\">&lt;&lt;</span> str <span class=\"token operator\">&lt;&lt;</span> endl<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"22\"></td><td><pre></pre></td></tr><tr><td data-num=\"23\"></td><td><pre>\tstr<span class=\"token punctuation\">.</span><span class=\"token function\">push_back</span><span class=\"token punctuation\">(</span><span class=\"token char\">'l'</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"24\"></td><td><pre>\tcout <span class=\"token operator\">&lt;&lt;</span> <span class=\"token string\">\"str: \"</span> <span class=\"token operator\">&lt;&lt;</span> str <span class=\"token operator\">&lt;&lt;</span> endl<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"25\"></td><td><pre></pre></td></tr><tr><td data-num=\"26\"></td><td><pre>\tstr<span class=\"token punctuation\">.</span><span class=\"token function\">push_back</span><span class=\"token punctuation\">(</span><span class=\"token char\">'d'</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"27\"></td><td><pre>\tcout <span class=\"token operator\">&lt;&lt;</span> <span class=\"token string\">\"str: \"</span> <span class=\"token operator\">&lt;&lt;</span> str <span class=\"token operator\">&lt;&lt;</span> endl<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"28\"></td><td><pre></pre></td></tr><tr><td data-num=\"29\"></td><td><pre>\t<span class=\"token keyword\">return</span> <span class=\"token number\">0</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"30\"></td><td><pre><span class=\"token punctuation\">&#125;</span></pre></td></tr></table></figure><h6 id=\"append\"><a class=\"anchor\" href=\"#append\">#</a> append</h6>\n<figure class=\"highlight cpp\"><figcaption data-lang=\"C++\"></figcaption><table><tr><td data-num=\"1\"></td><td><pre>string<span class=\"token operator\">&amp;</span> <span class=\"token function\">append</span> <span class=\"token punctuation\">(</span><span class=\"token keyword\">const</span> string<span class=\"token operator\">&amp;</span> str<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"2\"></td><td><pre>string<span class=\"token operator\">&amp;</span> <span class=\"token function\">append</span> <span class=\"token punctuation\">(</span><span class=\"token keyword\">const</span> string<span class=\"token operator\">&amp;</span> str<span class=\"token punctuation\">,</span> size_t subpos<span class=\"token punctuation\">,</span> size_t sublen <span class=\"token operator\">=</span> npos<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"3\"></td><td><pre>string<span class=\"token operator\">&amp;</span> <span class=\"token function\">append</span> <span class=\"token punctuation\">(</span><span class=\"token keyword\">const</span> <span class=\"token keyword\">char</span><span class=\"token operator\">*</span> s<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"4\"></td><td><pre>string<span class=\"token operator\">&amp;</span> <span class=\"token function\">append</span> <span class=\"token punctuation\">(</span><span class=\"token keyword\">const</span> <span class=\"token keyword\">char</span><span class=\"token operator\">*</span> s<span class=\"token punctuation\">,</span> size_t n<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"5\"></td><td><pre>string<span class=\"token operator\">&amp;</span> <span class=\"token function\">append</span> <span class=\"token punctuation\">(</span>size_t n<span class=\"token punctuation\">,</span> <span class=\"token keyword\">char</span> c<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr></table></figure><p>append 用于在字符串后追加一个字符串，有很多重构形式。比方说上面列出的几个（还有更多）。</p>\n<p>它们的用法看参数名就能理解，下面直接演示一下：</p>\n<figure class=\"highlight cpp\"><figcaption data-lang=\"C++\"></figcaption><table><tr><td data-num=\"1\"></td><td><pre><span class=\"token macro property\"><span class=\"token directive-hash\">#</span><span class=\"token directive keyword\">include</span> <span class=\"token string\">&lt;iostream></span></span></pre></td></tr><tr><td data-num=\"2\"></td><td><pre><span class=\"token macro property\"><span class=\"token directive-hash\">#</span><span class=\"token directive keyword\">include</span> <span class=\"token string\">&lt;string></span></span></pre></td></tr><tr><td data-num=\"3\"></td><td><pre></pre></td></tr><tr><td data-num=\"4\"></td><td><pre><span class=\"token keyword\">using</span> <span class=\"token keyword\">namespace</span> std<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"5\"></td><td><pre></pre></td></tr><tr><td data-num=\"6\"></td><td><pre><span class=\"token keyword\">int</span> <span class=\"token function\">main</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"7\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"8\"></td><td><pre>\tstring s <span class=\"token operator\">=</span> <span class=\"token string\">\"append:\"</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"9\"></td><td><pre>\tstring t <span class=\"token operator\">=</span> <span class=\"token string\">\"uvwxyz\"</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"10\"></td><td><pre>\ts<span class=\"token punctuation\">.</span><span class=\"token function\">append</span><span class=\"token punctuation\">(</span>t<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\t\t<span class=\"token comment\">// 将字符串 t 的内容追加到字符串 s 的末尾</span></pre></td></tr><tr><td data-num=\"11\"></td><td><pre>\tcout <span class=\"token operator\">&lt;&lt;</span> s <span class=\"token operator\">&lt;&lt;</span> endl<span class=\"token punctuation\">;</span>\t<span class=\"token comment\">// append:uvwxyz</span></pre></td></tr><tr><td data-num=\"12\"></td><td><pre>\ts<span class=\"token punctuation\">.</span><span class=\"token function\">append</span><span class=\"token punctuation\">(</span>t<span class=\"token punctuation\">,</span> <span class=\"token number\">2</span><span class=\"token punctuation\">,</span> <span class=\"token number\">3</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\t<span class=\"token comment\">// 将字符串 t 的子串（从 t [2] 开始数 3 位）追加到字符串 s 的末尾</span></pre></td></tr><tr><td data-num=\"13\"></td><td><pre>\tcout <span class=\"token operator\">&lt;&lt;</span> s <span class=\"token operator\">&lt;&lt;</span> endl<span class=\"token punctuation\">;</span>\t<span class=\"token comment\">// append:uvwxyzwxy</span></pre></td></tr><tr><td data-num=\"14\"></td><td><pre>\ts<span class=\"token punctuation\">.</span><span class=\"token function\">append</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"123\"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\t<span class=\"token comment\">// 将字符串 \"123\" 追加到字符串 s 的末尾</span></pre></td></tr><tr><td data-num=\"15\"></td><td><pre>\tcout <span class=\"token operator\">&lt;&lt;</span> s <span class=\"token operator\">&lt;&lt;</span> endl<span class=\"token punctuation\">;</span>\t<span class=\"token comment\">// append:uvwxyzwxy123</span></pre></td></tr><tr><td data-num=\"16\"></td><td><pre>\ts<span class=\"token punctuation\">.</span><span class=\"token function\">append</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"456\"</span><span class=\"token punctuation\">,</span> <span class=\"token number\">2</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\t<span class=\"token comment\">// 将字符串 \"456\" 的前 2 个字符追加到字符串 s 的末尾</span></pre></td></tr><tr><td data-num=\"17\"></td><td><pre>\tcout <span class=\"token operator\">&lt;&lt;</span> s <span class=\"token operator\">&lt;&lt;</span> endl<span class=\"token punctuation\">;</span>\t<span class=\"token comment\">// append:uvwxyzwxy12345</span></pre></td></tr><tr><td data-num=\"18\"></td><td><pre>\ts<span class=\"token punctuation\">.</span><span class=\"token function\">append</span><span class=\"token punctuation\">(</span><span class=\"token number\">3</span><span class=\"token punctuation\">,</span> <span class=\"token char\">'x'</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\t<span class=\"token comment\">// 将字符 'x' 追加到字符串 s 的末尾 3 次</span></pre></td></tr><tr><td data-num=\"19\"></td><td><pre>\tcout <span class=\"token operator\">&lt;&lt;</span> s <span class=\"token operator\">&lt;&lt;</span> endl<span class=\"token punctuation\">;</span>\t<span class=\"token comment\">// append:uvwxyzwxy12345xxx</span></pre></td></tr><tr><td data-num=\"20\"></td><td><pre></pre></td></tr><tr><td data-num=\"21\"></td><td><pre>\t<span class=\"token keyword\">return</span> <span class=\"token number\">0</span><span class=\"token punctuation\">;</span> </pre></td></tr><tr><td data-num=\"22\"></td><td><pre><span class=\"token punctuation\">&#125;</span></pre></td></tr></table></figure><h6 id=\"operator-2\"><a class=\"anchor\" href=\"#operator-2\">#</a> operator+=</h6>\n<figure class=\"highlight cpp\"><figcaption data-lang=\"C++\"></figcaption><table><tr><td data-num=\"1\"></td><td><pre>string<span class=\"token operator\">&amp;</span> <span class=\"token keyword\">operator</span><span class=\"token operator\">+=</span> <span class=\"token punctuation\">(</span><span class=\"token keyword\">const</span> string<span class=\"token operator\">&amp;</span> str<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"2\"></td><td><pre>string<span class=\"token operator\">&amp;</span> <span class=\"token keyword\">operator</span><span class=\"token operator\">+=</span> <span class=\"token punctuation\">(</span><span class=\"token keyword\">const</span> <span class=\"token keyword\">char</span><span class=\"token operator\">*</span> s<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"3\"></td><td><pre>string<span class=\"token operator\">&amp;</span> <span class=\"token keyword\">operator</span><span class=\"token operator\">+=</span> <span class=\"token punctuation\">(</span><span class=\"token keyword\">char</span> c<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr></table></figure><p>同样是在字符串后追加一个字符串 str。</p>\n<figure class=\"highlight cpp\"><figcaption data-lang=\"C++\"></figcaption><table><tr><td data-num=\"1\"></td><td><pre><span class=\"token macro property\"><span class=\"token directive-hash\">#</span><span class=\"token directive keyword\">include</span> <span class=\"token string\">&lt;iostream></span></span></pre></td></tr><tr><td data-num=\"2\"></td><td><pre><span class=\"token macro property\"><span class=\"token directive-hash\">#</span><span class=\"token directive keyword\">include</span> <span class=\"token string\">&lt;string></span></span></pre></td></tr><tr><td data-num=\"3\"></td><td><pre></pre></td></tr><tr><td data-num=\"4\"></td><td><pre><span class=\"token keyword\">using</span> <span class=\"token keyword\">namespace</span> std<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"5\"></td><td><pre></pre></td></tr><tr><td data-num=\"6\"></td><td><pre><span class=\"token keyword\">int</span> <span class=\"token function\">main</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"7\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"8\"></td><td><pre>\tstring s <span class=\"token operator\">=</span> <span class=\"token string\">\"append:\"</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"9\"></td><td><pre>\tcout <span class=\"token operator\">&lt;&lt;</span> <span class=\"token punctuation\">(</span>s <span class=\"token operator\">+=</span> <span class=\"token string\">\"abc\"</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">&lt;&lt;</span> endl<span class=\"token punctuation\">;</span>\t<span class=\"token comment\">// append:abc</span></pre></td></tr><tr><td data-num=\"10\"></td><td><pre>\tcout <span class=\"token operator\">&lt;&lt;</span> <span class=\"token punctuation\">(</span>s <span class=\"token operator\">+=</span> s<span class=\"token punctuation\">)</span> <span class=\"token operator\">&lt;&lt;</span> endl<span class=\"token punctuation\">;</span>\t\t<span class=\"token comment\">// append:abcappend:abc</span></pre></td></tr><tr><td data-num=\"11\"></td><td><pre>\tcout <span class=\"token operator\">&lt;&lt;</span> <span class=\"token punctuation\">(</span>s <span class=\"token operator\">+=</span> <span class=\"token char\">'.'</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">&lt;&lt;</span> endl<span class=\"token punctuation\">;</span>\t\t<span class=\"token comment\">// append:abcappend:abc.</span></pre></td></tr><tr><td data-num=\"12\"></td><td><pre></pre></td></tr><tr><td data-num=\"13\"></td><td><pre>\t<span class=\"token keyword\">return</span> <span class=\"token number\">0</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"14\"></td><td><pre><span class=\"token punctuation\">&#125;</span></pre></td></tr></table></figure><h6 id=\"c_str\"><a class=\"anchor\" href=\"#c_str\">#</a> c_str</h6>\n<p><code>const char* c_str() const noexcept;</code></p>\n<p>c_str 函数将 C++ 字符串转换为 C 字符串。使用简单无需示例。</p>\n<h6 id=\"find\"><a class=\"anchor\" href=\"#find\">#</a> find</h6>\n<h6 id=\"rfind\"><a class=\"anchor\" href=\"#rfind\">#</a> rfind</h6>\n<h6 id=\"npos\"><a class=\"anchor\" href=\"#npos\">#</a> npos</h6>\n<h6 id=\"substr\"><a class=\"anchor\" href=\"#substr\">#</a> substr</h6>\n<h5 id=\"string类非成员函数\"><a class=\"anchor\" href=\"#string类非成员函数\">#</a> string 类非成员函数</h5>\n<h6 id=\"operator-3\"><a class=\"anchor\" href=\"#operator-3\">#</a> operator+</h6>\n<h6 id=\"operator-4\"><a class=\"anchor\" href=\"#operator-4\">#</a> operator&gt;&gt;</h6>\n<h6 id=\"operator-5\"><a class=\"anchor\" href=\"#operator-5\">#</a> operator&lt;&lt;</h6>\n<h6 id=\"getline\"><a class=\"anchor\" href=\"#getline\">#</a> getline</h6>\n<h6 id=\"relational-operators\"><a class=\"anchor\" href=\"#relational-operators\">#</a> relational operators(==、!=、&lt;、&lt;=、&gt;、&gt;=)</h6>\n",
            "tags": [
                "计算机科学",
                "C++笔记",
                "C++",
                "string"
            ]
        },
        {
            "id": "https://www.starlinglin.top/computer-science/misc/K&R%E9%A3%8E%E6%A0%BC%E4%B8%8EAllman%E9%A3%8E%E6%A0%BC/",
            "url": "https://www.starlinglin.top/computer-science/misc/K&R%E9%A3%8E%E6%A0%BC%E4%B8%8EAllman%E9%A3%8E%E6%A0%BC/",
            "title": "K&R风格与Allman风格",
            "date_published": "2024-08-23T15:21:51.000Z",
            "content_html": "<p>我们在看别人写的代码时，会发现每个人都有自己的代码风格，这可能体现在注释的习惯上、命名的方法上、变量的使用上。而关于代码中的花括号，我们发现，主流只有两种对齐方法。</p>\n<p>一种是将花括号头直接与相应的语句放在同一行，这种被称之为<mark> K&amp;R 风格</mark>：</p>\n<figure class=\"highlight cpp\"><figcaption data-lang=\"C++\"></figcaption><table><tr><td data-num=\"1\"></td><td><pre><span class=\"token keyword\">void</span> <span class=\"token function\">f</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"2\"></td><td><pre>    <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">.</span><span class=\"token punctuation\">.</span><span class=\"token punctuation\">.</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"3\"></td><td><pre>        <span class=\"token comment\">//...</span></pre></td></tr><tr><td data-num=\"4\"></td><td><pre>    <span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"5\"></td><td><pre>    <span class=\"token comment\">//...</span></pre></td></tr><tr><td data-num=\"6\"></td><td><pre><span class=\"token punctuation\">&#125;</span></pre></td></tr></table></figure><p>另一种是将花括号头放在单独的一行，并且与花括号尾对齐，这种被称之为<mark> Allman 风格</mark>：</p>\n<figure class=\"highlight cpp\"><figcaption data-lang=\"C++\"></figcaption><table><tr><td data-num=\"1\"></td><td><pre><span class=\"token keyword\">void</span> <span class=\"token function\">f</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"2\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"3\"></td><td><pre>    <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">.</span><span class=\"token punctuation\">.</span><span class=\"token punctuation\">.</span><span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"4\"></td><td><pre>    <span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"5\"></td><td><pre>        <span class=\"token comment\">//...</span></pre></td></tr><tr><td data-num=\"6\"></td><td><pre>    <span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"7\"></td><td><pre>    <span class=\"token comment\">//...</span></pre></td></tr><tr><td data-num=\"8\"></td><td><pre><span class=\"token punctuation\">&#125;</span></pre></td></tr></table></figure><h3 id=\"kr风格紧凑风\"><a class=\"anchor\" href=\"#kr风格紧凑风\">#</a> K&amp;R 风格（紧凑风）</h3>\n<p>K&amp;R 风格来源于 C 语言的创建者 Brian Kernighan 和 Dennis Ritchie。他们在《The C Programming Language》一书中广泛使用了这种风格，因此成为了现在很多 C 和 C++ 开发者的默认选择。</p>\n<p>使用 K&amp;R 风格能够节省垂直空间，使代码更加紧凑，减少了滚动浏览页面的频率。</p>\n<h3 id=\"allman风格折叠风\"><a class=\"anchor\" href=\"#allman风格折叠风\">#</a> Allman 风格（折叠风）</h3>\n<p>Allman 风格来源于 Eric Allman，他是 BSD UNIX 的开发者之一。这种风格是他在早期 Unix 系统代码中推广的。这种风格增强了代码的可读性，尤其是在大段代码中，每一个代码块的位置都很清晰。更容易在视觉上区分代码块的开始和结束，减少嵌套结构不清晰而导致的错误。同时有助于调试代码时快速的定位问题所属代码块。</p>\n<h3 id=\"如何选择代码风格\"><a class=\"anchor\" href=\"#如何选择代码风格\">#</a> 如何选择代码风格</h3>\n<p>这两种风格都有很多使用者，具体选择哪种更多是个人习惯或者团队规范的结果。一般来说如果更注重代码的可读性，尤其是经常处理长代码段时，Allman 风格会更合适。但是如果没有团队的强制要求，最好还是选择自己觉得最舒服的风格。</p>\n",
            "tags": [
                "计算机科学",
                "杂项",
                "代码风格"
            ]
        },
        {
            "id": "https://www.starlinglin.top/computer-science/Cpp-programme-note/%E6%A4%8B%E9%B8%9FC++%E7%AC%94%E8%AE%B0%20%EF%BC%836%EF%BC%9A%E6%A8%A1%E6%9D%BF%E7%9A%84%E5%9F%BA%E7%A1%80%E7%94%A8%E6%B3%95/",
            "url": "https://www.starlinglin.top/computer-science/Cpp-programme-note/%E6%A4%8B%E9%B8%9FC++%E7%AC%94%E8%AE%B0%20%EF%BC%836%EF%BC%9A%E6%A8%A1%E6%9D%BF%E7%9A%84%E5%9F%BA%E7%A1%80%E7%94%A8%E6%B3%95/",
            "title": "椋鸟C++笔记#6：模板的基础用法",
            "date_published": "2024-08-23T14:10:19.000Z",
            "content_html": "<div class=\"note warning\">\n<p>本系列暴死，不会更新了。</p>\n</div>\n<div class=\"note info\">\n<p>该系列为本人的学习笔记，主要由本人整理书写而成。部分内容来自教材、视频课程等，不能保证完全原创性。</p>\n</div>\n<p>萌新的学习笔记，写错了恳请斧正。</p>\n<h3 id=\"泛式编程\"><a class=\"anchor\" href=\"#泛式编程\">#</a> 泛式编程</h3>\n<p>在 C 语言笔记 #22 中，我们提到了泛式编程<strong>可以减少对特定数据类型的依赖</strong>，并且使用泛型指针 <code>void*</code>  在 C 语言中实现了一个 “万能” 的冒泡排序。而在 C++ 中，泛式编程更加容易，因为 C++ 提供了模版这么一个概念。</p>\n<h3 id=\"函数模板\"><a class=\"anchor\" href=\"#函数模板\">#</a> 函数模板</h3>\n<p>一个函数模板就代表了一个函数家族，函数模板与类型无关，只在使用时才被参数化，根据参数的类型来产生函数的特定版本。</p>\n<p>如果我们想在函数中使用未定的类型，我们只要在函数的声明和定义前各加上一行 template 语句。</p>\n<p>template 语句的格式为：</p>\n<figure class=\"highlight cpp\"><figcaption data-lang=\"C++\"></figcaption><table><tr><td data-num=\"1\"></td><td><pre><span class=\"token keyword\">template</span> <span class=\"token operator\">&lt;</span><span class=\"token keyword\">typename</span> <span class=\"token class-name\">T1</span><span class=\"token punctuation\">,</span> <span class=\"token keyword\">typename</span> <span class=\"token class-name\">T2</span><span class=\"token punctuation\">,</span> <span class=\"token punctuation\">.</span><span class=\"token punctuation\">.</span><span class=\"token punctuation\">.</span><span class=\"token punctuation\">,</span> <span class=\"token keyword\">typename</span> <span class=\"token class-name\">Tn</span><span class=\"token operator\">></span></pre></td></tr><tr><td data-num=\"2\"></td><td><pre><span class=\"token comment\">// 下面直接接模版函数的本体即可，本体中就可以利用我们设置的模版类型 T1,T2……</span></pre></td></tr><tr><td data-num=\"3\"></td><td><pre><span class=\"token comment\">// 这里 typename 也可以替换为 class，但是这样不符合自然语言逻辑：</span></pre></td></tr><tr><td data-num=\"4\"></td><td><pre><span class=\"token keyword\">template</span> <span class=\"token operator\">&lt;</span><span class=\"token keyword\">class</span> <span class=\"token class-name\">T1</span><span class=\"token punctuation\">,</span> <span class=\"token keyword\">class</span> <span class=\"token class-name\">T2</span><span class=\"token punctuation\">,</span> <span class=\"token punctuation\">.</span><span class=\"token punctuation\">.</span><span class=\"token punctuation\">.</span><span class=\"token punctuation\">,</span> <span class=\"token keyword\">class</span> <span class=\"token class-name\">Tn</span><span class=\"token operator\">></span></pre></td></tr></table></figure><p>比方说如果我们想写一个任意类型的加法函数，只需要这样：</p>\n<figure class=\"highlight cpp\"><figcaption data-lang=\"C++\"></figcaption><table><tr><td data-num=\"1\"></td><td><pre><span class=\"token keyword\">template</span> <span class=\"token operator\">&lt;</span><span class=\"token keyword\">typename</span> <span class=\"token class-name\">T</span><span class=\"token operator\">></span></pre></td></tr><tr><td data-num=\"2\"></td><td><pre>T <span class=\"token function\">add</span><span class=\"token punctuation\">(</span>T a<span class=\"token punctuation\">,</span> T b<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"3\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"4\"></td><td><pre>    <span class=\"token keyword\">return</span> a <span class=\"token operator\">+</span> b<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"5\"></td><td><pre><span class=\"token punctuation\">&#125;</span></pre></td></tr></table></figure><p>但是这里要求参数 a 和参数 b 是同一个类型的变量，如果我们的函数涉及到多个互不关联的未定的类型，就需要在 template 的形参列表中加上一些东西，比方说写一个比较两个类型变量的内存大小的函数：</p>\n<figure class=\"highlight cpp\"><figcaption data-lang=\"C++\"></figcaption><table><tr><td data-num=\"1\"></td><td><pre><span class=\"token keyword\">template</span> <span class=\"token operator\">&lt;</span><span class=\"token keyword\">typename</span> <span class=\"token class-name\">T1</span><span class=\"token punctuation\">,</span> <span class=\"token keyword\">typename</span> <span class=\"token class-name\">T2</span><span class=\"token operator\">></span></pre></td></tr><tr><td data-num=\"2\"></td><td><pre><span class=\"token keyword\">bool</span> <span class=\"token function\">TypeSizeBigger</span><span class=\"token punctuation\">(</span>T1 x<span class=\"token punctuation\">,</span> T2 y<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"3\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"4\"></td><td><pre>    <span class=\"token keyword\">return</span> <span class=\"token punctuation\">(</span><span class=\"token keyword\">sizeof</span><span class=\"token punctuation\">(</span>x<span class=\"token punctuation\">)</span> <span class=\"token operator\">></span> <span class=\"token keyword\">sizeof</span><span class=\"token punctuation\">(</span>y<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">?</span> <span class=\"token boolean\">true</span> <span class=\"token operator\">:</span> <span class=\"token boolean\">false</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"5\"></td><td><pre><span class=\"token punctuation\">&#125;</span></pre></td></tr></table></figure><h4 id=\"函数模板的实例化\"><a class=\"anchor\" href=\"#函数模板的实例化\">#</a> 函数模板的实例化</h4>\n<p>在编译阶段，编译器<strong>根据传入模板的实参类型来推演生成对应类型的函数以供调用</strong>。</p>\n<p>比方说对于上面的 add 函数在程序中实际有三种类型传入进来调用。那么编译器实际上在编译时就根据模板生成了三个仅类型不同的函数，每一个用于处理不同的类型的调用。用不同类型的参数使用函数模板是，也称为函数模板的<strong>实例化</strong>。</p>\n<p>实例化分为<strong>隐式实例化</strong>和<strong>显示实例化</strong>：</p>\n<h5 id=\"隐式实例化\"><a class=\"anchor\" href=\"#隐式实例化\">#</a> 隐式实例化</h5>\n<p>隐式实例化就是让编译器根据实参自己推演模板参数的实际类型。</p>\n<figure class=\"highlight cpp\"><figcaption data-lang=\"C++\"></figcaption><table><tr><td data-num=\"1\"></td><td><pre><span class=\"token keyword\">template</span> <span class=\"token operator\">&lt;</span><span class=\"token keyword\">typename</span> <span class=\"token class-name\">T</span><span class=\"token operator\">></span></pre></td></tr><tr><td data-num=\"2\"></td><td><pre>T <span class=\"token function\">Add</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">const</span> T<span class=\"token operator\">&amp;</span> a<span class=\"token punctuation\">,</span> <span class=\"token keyword\">const</span> T<span class=\"token operator\">&amp;</span> b<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"3\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"4\"></td><td><pre>    <span class=\"token keyword\">return</span> a <span class=\"token operator\">+</span> b<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"5\"></td><td><pre><span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"6\"></td><td><pre></pre></td></tr><tr><td data-num=\"7\"></td><td><pre><span class=\"token keyword\">int</span> <span class=\"token function\">main</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"8\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"9\"></td><td><pre>    <span class=\"token keyword\">int</span> a <span class=\"token operator\">=</span> <span class=\"token number\">5</span><span class=\"token punctuation\">,</span> b <span class=\"token operator\">=</span> <span class=\"token number\">6</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"10\"></td><td><pre>    <span class=\"token keyword\">double</span> c <span class=\"token operator\">=</span> <span class=\"token number\">7.1</span><span class=\"token punctuation\">,</span> d <span class=\"token operator\">=</span> <span class=\"token number\">8.2</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"11\"></td><td><pre>    <span class=\"token function\">Add</span><span class=\"token punctuation\">(</span>a<span class=\"token punctuation\">,</span> b<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"12\"></td><td><pre>    <span class=\"token function\">Add</span><span class=\"token punctuation\">(</span>c<span class=\"token punctuation\">,</span> d<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"13\"></td><td><pre>    </pre></td></tr><tr><td data-num=\"14\"></td><td><pre>    <span class=\"token keyword\">return</span> <span class=\"token number\">0</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"15\"></td><td><pre><span class=\"token punctuation\">&#125;</span></pre></td></tr></table></figure><h5 id=\"显式实例化\"><a class=\"anchor\" href=\"#显式实例化\">#</a> 显式实例化</h5>\n<p>显式实例化就是在调用时于函数名后加一个 <code>&lt;&gt;</code>  来指定模板参数的实际类型：</p>\n<figure class=\"highlight cpp\"><figcaption data-lang=\"C++\"></figcaption><table><tr><td data-num=\"1\"></td><td><pre><span class=\"token keyword\">template</span> <span class=\"token operator\">&lt;</span><span class=\"token keyword\">typename</span> <span class=\"token class-name\">T</span><span class=\"token operator\">></span></pre></td></tr><tr><td data-num=\"2\"></td><td><pre>T <span class=\"token function\">Add</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">const</span> T<span class=\"token operator\">&amp;</span> a<span class=\"token punctuation\">,</span> <span class=\"token keyword\">const</span> T<span class=\"token operator\">&amp;</span> b<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"3\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"4\"></td><td><pre>    <span class=\"token keyword\">return</span> a <span class=\"token operator\">+</span> b<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"5\"></td><td><pre><span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"6\"></td><td><pre></pre></td></tr><tr><td data-num=\"7\"></td><td><pre><span class=\"token keyword\">int</span> <span class=\"token function\">main</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"8\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"9\"></td><td><pre>    <span class=\"token keyword\">int</span> a <span class=\"token operator\">=</span> <span class=\"token number\">5</span><span class=\"token punctuation\">,</span> b <span class=\"token operator\">=</span> <span class=\"token number\">6</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"10\"></td><td><pre>    <span class=\"token keyword\">double</span> c <span class=\"token operator\">=</span> <span class=\"token number\">7.1</span><span class=\"token punctuation\">,</span> d <span class=\"token operator\">=</span> <span class=\"token number\">8.2</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"11\"></td><td><pre>    <span class=\"token generic-function\"><span class=\"token function\">Add</span><span class=\"token generic class-name\"><span class=\"token operator\">&lt;</span><span class=\"token keyword\">int</span><span class=\"token operator\">></span></span></span><span class=\"token punctuation\">(</span>a<span class=\"token punctuation\">,</span> b<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"12\"></td><td><pre>    <span class=\"token generic-function\"><span class=\"token function\">Add</span><span class=\"token generic class-name\"><span class=\"token operator\">&lt;</span><span class=\"token keyword\">double</span><span class=\"token operator\">></span></span></span><span class=\"token punctuation\">(</span>c<span class=\"token punctuation\">,</span> d<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"13\"></td><td><pre>    </pre></td></tr><tr><td data-num=\"14\"></td><td><pre>    <span class=\"token keyword\">return</span> <span class=\"token number\">0</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"15\"></td><td><pre><span class=\"token punctuation\">&#125;</span></pre></td></tr></table></figure><p>如果类型不匹配，编译器将会尝试进行隐式类型转换，如果无法转换成功就会报错。</p>\n<h4 id=\"模板函数的匹配原则\"><a class=\"anchor\" href=\"#模板函数的匹配原则\">#</a> 模板函数的匹配原则</h4>\n<ol>\n<li>\n<p>可以有非模板函数与模板函数同名，而且该函数模板还可以被实例化为这个非模板函数。</p>\n<figure class=\"highlight cpp\"><figcaption data-lang=\"C++\"></figcaption><table><tr><td data-num=\"1\"></td><td><pre><span class=\"token comment\">// 专门处理 int 类型</span></pre></td></tr><tr><td data-num=\"2\"></td><td><pre><span class=\"token keyword\">int</span> <span class=\"token function\">f</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">int</span> a<span class=\"token punctuation\">,</span> <span class=\"token keyword\">int</span> b<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"3\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"4\"></td><td><pre>    <span class=\"token keyword\">return</span> a <span class=\"token operator\">+</span> b <span class=\"token operator\">+</span> <span class=\"token number\">1</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"5\"></td><td><pre><span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"6\"></td><td><pre></pre></td></tr><tr><td data-num=\"7\"></td><td><pre><span class=\"token keyword\">template</span> <span class=\"token operator\">&lt;</span><span class=\"token keyword\">typename</span> <span class=\"token class-name\">T</span><span class=\"token operator\">></span></pre></td></tr><tr><td data-num=\"8\"></td><td><pre>T <span class=\"token function\">f</span><span class=\"token punctuation\">(</span>T a<span class=\"token punctuation\">,</span> T b<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"9\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"10\"></td><td><pre>    <span class=\"token keyword\">return</span> a <span class=\"token operator\">+</span> b<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"11\"></td><td><pre><span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"12\"></td><td><pre></pre></td></tr><tr><td data-num=\"13\"></td><td><pre><span class=\"token keyword\">int</span> <span class=\"token function\">main</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"14\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"15\"></td><td><pre>\tcout <span class=\"token operator\">&lt;&lt;</span> <span class=\"token function\">f</span><span class=\"token punctuation\">(</span><span class=\"token number\">1</span><span class=\"token punctuation\">,</span> <span class=\"token number\">2</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">&lt;&lt;</span> endl<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"16\"></td><td><pre>\tcout <span class=\"token operator\">&lt;&lt;</span> <span class=\"token generic-function\"><span class=\"token function\">f</span><span class=\"token generic class-name\"><span class=\"token operator\">&lt;</span><span class=\"token keyword\">int</span><span class=\"token operator\">></span></span></span><span class=\"token punctuation\">(</span><span class=\"token number\">1</span><span class=\"token punctuation\">,</span> <span class=\"token number\">2</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">&lt;&lt;</span> endl<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"17\"></td><td><pre>\t</pre></td></tr><tr><td data-num=\"18\"></td><td><pre>\t<span class=\"token keyword\">return</span> <span class=\"token number\">0</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"19\"></td><td><pre><span class=\"token punctuation\">&#125;</span></pre></td></tr></table></figure><p>此时这个函数输出是先 4 后 3，为什么呢？因为<strong>在能够与非模板函数匹配时，编译器不会再特化生成一个对应的函数，而是直接调用。而在指定模板实例化时，编译器依旧会按照模板生成并调用。</strong></p>\n<p>注意这里并不会冲突报错，哪怕这非模板函数和生成的函数的函数名（包括返回值与参数列表）都一样。因为在编译过程中，函数的名称会经过修饰以确保函数的唯一性。虽然模板函数和普通函数在表面上看起来参数和返回类型相同，但由于模板的存在，编译器在生成模板函数时会应用不同的名称修饰规则。</p>\n<p>在 linux gcc 环境下，我们测试到非模板函数 f 的原型和修饰后的函数符号如下：</p>\n<figure class=\"highlight cpp\"><figcaption data-lang=\"C++\"></figcaption><table><tr><td data-num=\"1\"></td><td><pre><span class=\"token keyword\">int</span> <span class=\"token function\">f</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">int</span> a<span class=\"token punctuation\">,</span> <span class=\"token keyword\">int</span> b<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"2\"></td><td><pre>_Z1fii</pre></td></tr></table></figure><p>其中 <code>_Z</code>  代表这是经过修饰的 C++ 符号， <code>1f</code>  代表名字长度为 1 且名字为 f， <code>ii</code>  代表参数类型为 <code>int, int</code> 。</p>\n<p>而模板生成函数的原型与函数符号为：</p>\n<figure class=\"highlight cpp\"><figcaption data-lang=\"C++\"></figcaption><table><tr><td data-num=\"1\"></td><td><pre><span class=\"token keyword\">template</span> <span class=\"token operator\">&lt;</span><span class=\"token keyword\">typename</span> <span class=\"token class-name\">T</span><span class=\"token operator\">></span></pre></td></tr><tr><td data-num=\"2\"></td><td><pre>T <span class=\"token generic-function\"><span class=\"token function\">f</span><span class=\"token generic class-name\"><span class=\"token operator\">&lt;</span><span class=\"token keyword\">int</span><span class=\"token operator\">></span></span></span><span class=\"token punctuation\">(</span>T a<span class=\"token punctuation\">,</span> T b<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"3\"></td><td><pre>_Z1fIiEii</pre></td></tr></table></figure><p>其中 <code>_Z</code>  代表这是经过修饰的 C++ 符号， <code>1f</code>  代表名字长度为 1 且名字为 f， <code>IiE</code>  代表这是一个模板实例化，其中 <code>i</code>  代表模板参数类型为 int，最后的 <code>ii</code>  代表参数类型为 <code>int, int</code> 。</p>\n</li>\n<li>\n<p>如果模板能够匹配产生一个更好的函数，则优先调用模板。</p>\n<figure class=\"highlight cpp\"><figcaption data-lang=\"C++\"></figcaption><table><tr><td data-num=\"1\"></td><td><pre><span class=\"token comment\">// 专门处理 int 类型</span></pre></td></tr><tr><td data-num=\"2\"></td><td><pre><span class=\"token keyword\">int</span> <span class=\"token function\">f</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">int</span> a<span class=\"token punctuation\">,</span> <span class=\"token keyword\">int</span> b<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"3\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"4\"></td><td><pre>    <span class=\"token keyword\">return</span> a <span class=\"token operator\">+</span> b <span class=\"token operator\">+</span> <span class=\"token number\">1</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"5\"></td><td><pre><span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"6\"></td><td><pre></pre></td></tr><tr><td data-num=\"7\"></td><td><pre><span class=\"token keyword\">template</span> <span class=\"token operator\">&lt;</span><span class=\"token keyword\">typename</span> <span class=\"token class-name\">T1</span><span class=\"token punctuation\">,</span> <span class=\"token keyword\">typename</span> <span class=\"token class-name\">T2</span><span class=\"token operator\">></span></pre></td></tr><tr><td data-num=\"8\"></td><td><pre>T1 <span class=\"token function\">f</span><span class=\"token punctuation\">(</span>T1 a<span class=\"token punctuation\">,</span> T2 b<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"9\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"10\"></td><td><pre>    <span class=\"token keyword\">return</span> a <span class=\"token operator\">+</span> b<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"11\"></td><td><pre><span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"12\"></td><td><pre></pre></td></tr><tr><td data-num=\"13\"></td><td><pre><span class=\"token keyword\">int</span> <span class=\"token function\">main</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"14\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"15\"></td><td><pre>\tcout <span class=\"token operator\">&lt;&lt;</span> <span class=\"token function\">f</span><span class=\"token punctuation\">(</span><span class=\"token number\">1.0</span><span class=\"token punctuation\">,</span> <span class=\"token number\">2</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">&lt;&lt;</span> endl<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"16\"></td><td><pre>\t</pre></td></tr><tr><td data-num=\"17\"></td><td><pre>\t<span class=\"token keyword\">return</span> <span class=\"token number\">0</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"18\"></td><td><pre><span class=\"token punctuation\">&#125;</span></pre></td></tr></table></figure><p>此时优先调用的是模板生成的函数。</p>\n<p><mark>注意：模板函数不允许自动类型转换，但是普通函数可以自动类型转换。</mark></p>\n</li>\n</ol>\n<h3 id=\"类模板\"><a class=\"anchor\" href=\"#类模板\">#</a> 类模板</h3>\n<p>与模板函数类似，我们可以定义模板类。模板类前同样需要 template 语句：</p>\n<figure class=\"highlight cpp\"><figcaption data-lang=\"C++\"></figcaption><table><tr><td data-num=\"1\"></td><td><pre><span class=\"token keyword\">template</span> <span class=\"token operator\">&lt;</span><span class=\"token keyword\">class</span> <span class=\"token class-name\">T1</span><span class=\"token punctuation\">,</span> <span class=\"token keyword\">class</span> <span class=\"token class-name\">T2</span><span class=\"token punctuation\">,</span> <span class=\"token punctuation\">.</span><span class=\"token punctuation\">.</span><span class=\"token punctuation\">.</span><span class=\"token punctuation\">,</span> <span class=\"token keyword\">class</span> <span class=\"token class-name\">Tn</span><span class=\"token operator\">></span></pre></td></tr><tr><td data-num=\"2\"></td><td><pre><span class=\"token comment\">// 下面直接接模板类即可</span></pre></td></tr></table></figure><p>比方说写一个动态顺序表模板类：</p>\n<figure class=\"highlight cpp\"><figcaption data-lang=\"C++\"></figcaption><table><tr><td data-num=\"1\"></td><td><pre><span class=\"token keyword\">template</span> <span class=\"token operator\">&lt;</span><span class=\"token keyword\">class</span> <span class=\"token class-name\">T</span><span class=\"token operator\">></span></pre></td></tr><tr><td data-num=\"2\"></td><td><pre><span class=\"token keyword\">class</span> <span class=\"token class-name\">SeqList</span></pre></td></tr><tr><td data-num=\"3\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"4\"></td><td><pre><span class=\"token keyword\">public</span><span class=\"token operator\">:</span></pre></td></tr><tr><td data-num=\"5\"></td><td><pre>\t<span class=\"token function\">SeqList</span><span class=\"token punctuation\">(</span>size_t capacity <span class=\"token operator\">=</span> <span class=\"token number\">10</span><span class=\"token punctuation\">)</span> </pre></td></tr><tr><td data-num=\"6\"></td><td><pre>\t\t<span class=\"token operator\">:</span> <span class=\"token function\">m_data</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">new</span> T<span class=\"token punctuation\">[</span>capacity<span class=\"token punctuation\">]</span><span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"7\"></td><td><pre>\t\t<span class=\"token punctuation\">,</span> <span class=\"token function\">m_capacity</span><span class=\"token punctuation\">(</span>capacity<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"8\"></td><td><pre>\t\t<span class=\"token punctuation\">,</span> <span class=\"token function\">m_size</span><span class=\"token punctuation\">(</span><span class=\"token number\">0</span><span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"9\"></td><td><pre>\t<span class=\"token punctuation\">&#123;</span><span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"10\"></td><td><pre></pre></td></tr><tr><td data-num=\"11\"></td><td><pre>\t<span class=\"token operator\">~</span><span class=\"token function\">SeqList</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"12\"></td><td><pre>\t<span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"13\"></td><td><pre>\t\t<span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>m_data<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"14\"></td><td><pre>\t\t\t<span class=\"token keyword\">delete</span><span class=\"token punctuation\">[</span><span class=\"token punctuation\">]</span> m_data<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"15\"></td><td><pre>\t\tm_size <span class=\"token operator\">=</span> m_capacity <span class=\"token operator\">=</span> <span class=\"token number\">0</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"16\"></td><td><pre>\t<span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"17\"></td><td><pre></pre></td></tr><tr><td data-num=\"18\"></td><td><pre>\t<span class=\"token keyword\">void</span> <span class=\"token function\">push_back</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">const</span> T<span class=\"token operator\">&amp;</span> value<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"19\"></td><td><pre>\t<span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"20\"></td><td><pre>\t\t<span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>m_size <span class=\"token operator\">==</span> m_capacity<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"21\"></td><td><pre>\t\t<span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"22\"></td><td><pre>\t\t\tsize_t new_capacity <span class=\"token operator\">=</span> m_capacity <span class=\"token operator\">*</span> <span class=\"token number\">2</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"23\"></td><td><pre>\t\t\tT<span class=\"token operator\">*</span> new_data <span class=\"token operator\">=</span> <span class=\"token keyword\">new</span> T<span class=\"token punctuation\">[</span>new_capacity<span class=\"token punctuation\">]</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"24\"></td><td><pre>\t\t\t<span class=\"token keyword\">for</span> <span class=\"token punctuation\">(</span>size_t i <span class=\"token operator\">=</span> <span class=\"token number\">0</span><span class=\"token punctuation\">;</span> i <span class=\"token operator\">&lt;</span> m_size<span class=\"token punctuation\">;</span> <span class=\"token operator\">++</span>i<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"25\"></td><td><pre>\t\t\t\tnew_data<span class=\"token punctuation\">[</span>i<span class=\"token punctuation\">]</span> <span class=\"token operator\">=</span> m_data<span class=\"token punctuation\">[</span>i<span class=\"token punctuation\">]</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"26\"></td><td><pre>\t\t\t<span class=\"token keyword\">delete</span><span class=\"token punctuation\">[</span><span class=\"token punctuation\">]</span> m_data<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"27\"></td><td><pre>\t\t\tm_data <span class=\"token operator\">=</span> new_data<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"28\"></td><td><pre>\t\t\tm_capacity <span class=\"token operator\">=</span> new_capacity<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"29\"></td><td><pre>\t\t<span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"30\"></td><td><pre>\t\tm_data<span class=\"token punctuation\">[</span>m_size<span class=\"token operator\">++</span><span class=\"token punctuation\">]</span> <span class=\"token operator\">=</span> value<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"31\"></td><td><pre>\t<span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"32\"></td><td><pre></pre></td></tr><tr><td data-num=\"33\"></td><td><pre>\t<span class=\"token keyword\">void</span> <span class=\"token function\">pop_back</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"34\"></td><td><pre>\t<span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"35\"></td><td><pre>\t\t<span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>m_size <span class=\"token operator\">></span> <span class=\"token number\">0</span><span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"36\"></td><td><pre>\t\t\t<span class=\"token operator\">--</span>m_size<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"37\"></td><td><pre>\t<span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"38\"></td><td><pre></pre></td></tr><tr><td data-num=\"39\"></td><td><pre>\tsize_t <span class=\"token function\">size</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token keyword\">const</span></pre></td></tr><tr><td data-num=\"40\"></td><td><pre>\t<span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"41\"></td><td><pre>\t\t<span class=\"token keyword\">return</span> m_size<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"42\"></td><td><pre>\t<span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"43\"></td><td><pre></pre></td></tr><tr><td data-num=\"44\"></td><td><pre>\tT<span class=\"token operator\">&amp;</span> <span class=\"token keyword\">operator</span><span class=\"token punctuation\">[</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">(</span>size_t index<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"45\"></td><td><pre>\t<span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"46\"></td><td><pre>\t\t<span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>index <span class=\"token operator\">>=</span> m_size<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"47\"></td><td><pre>\t\t\t<span class=\"token keyword\">throw</span> <span class=\"token function\">out_of_range</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"Index out of range\"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"48\"></td><td><pre>\t\t<span class=\"token keyword\">return</span> m_data<span class=\"token punctuation\">[</span>index<span class=\"token punctuation\">]</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"49\"></td><td><pre>\t<span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"50\"></td><td><pre></pre></td></tr><tr><td data-num=\"51\"></td><td><pre></pre></td></tr><tr><td data-num=\"52\"></td><td><pre><span class=\"token keyword\">private</span><span class=\"token operator\">:</span></pre></td></tr><tr><td data-num=\"53\"></td><td><pre>\tT<span class=\"token operator\">*</span> m_data<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"54\"></td><td><pre>\tsize_t m_capacity<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"55\"></td><td><pre>\tsize_t m_size<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"56\"></td><td><pre><span class=\"token punctuation\">&#125;</span><span class=\"token punctuation\">;</span></pre></td></tr></table></figure><h4 id=\"类模板声明与定义分离\"><a class=\"anchor\" href=\"#类模板声明与定义分离\">#</a> 类模板声明与定义分离</h4>\n<p>如果想要类模板声明与定义分离，我们以上面的动态顺序表的析构为例：</p>\n<figure class=\"highlight cpp\"><figcaption data-lang=\"C++\"></figcaption><table><tr><td data-num=\"1\"></td><td><pre><span class=\"token keyword\">template</span> <span class=\"token operator\">&lt;</span><span class=\"token keyword\">class</span> <span class=\"token class-name\">T</span><span class=\"token operator\">></span></pre></td></tr><tr><td data-num=\"2\"></td><td><pre><span class=\"token keyword\">class</span> <span class=\"token class-name\">SeqList</span></pre></td></tr><tr><td data-num=\"3\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"4\"></td><td><pre><span class=\"token keyword\">public</span><span class=\"token operator\">:</span></pre></td></tr><tr><td data-num=\"5\"></td><td><pre>\t<span class=\"token comment\">//...</span></pre></td></tr><tr><td data-num=\"6\"></td><td><pre>\t<span class=\"token operator\">~</span><span class=\"token function\">SeqList</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"7\"></td><td><pre>    <span class=\"token comment\">//...</span></pre></td></tr><tr><td data-num=\"8\"></td><td><pre><span class=\"token punctuation\">&#125;</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"9\"></td><td><pre></pre></td></tr><tr><td data-num=\"10\"></td><td><pre><span class=\"token keyword\">template</span> <span class=\"token operator\">&lt;</span><span class=\"token keyword\">class</span> <span class=\"token class-name\">T</span><span class=\"token operator\">></span></pre></td></tr><tr><td data-num=\"11\"></td><td><pre>SeqList<span class=\"token operator\">&lt;</span>T<span class=\"token operator\">></span><span class=\"token double-colon punctuation\">::</span><span class=\"token operator\">~</span><span class=\"token function\">SeqList</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"12\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"13\"></td><td><pre>    <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>m_data<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"14\"></td><td><pre>        <span class=\"token keyword\">delete</span><span class=\"token punctuation\">[</span><span class=\"token punctuation\">]</span> m_data<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"15\"></td><td><pre>\tm_size <span class=\"token operator\">=</span> m_capacity <span class=\"token operator\">=</span> <span class=\"token number\">0</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"16\"></td><td><pre><span class=\"token punctuation\">&#125;</span></pre></td></tr></table></figure><p>我们看到如果类模板的函数在类外定义时，需要加模板参数列表。</p>\n<h4 id=\"类模板的实例化\"><a class=\"anchor\" href=\"#类模板的实例化\">#</a> 类模板的实例化</h4>\n<p>类模板的实例化与函数模板类似，在类名称之后加上 <code>&lt;&gt;</code>  以限定类型。（类模板不能隐式实例化）</p>\n<figure class=\"highlight cpp\"><figcaption data-lang=\"C++\"></figcaption><table><tr><td data-num=\"1\"></td><td><pre>SeqList<span class=\"token operator\">&lt;</span><span class=\"token keyword\">int</span><span class=\"token operator\">></span> s1<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"2\"></td><td><pre>\tSeqList<span class=\"token operator\">&lt;</span><span class=\"token keyword\">double</span><span class=\"token operator\">></span> s2<span class=\"token punctuation\">;</span></pre></td></tr></table></figure>",
            "tags": [
                "计算机科学",
                "C++笔记",
                "C++",
                "模板"
            ]
        },
        {
            "id": "https://www.starlinglin.top/computer-science/Cpp-programme-note/%E6%A4%8B%E9%B8%9FC++%E7%AC%94%E8%AE%B0%20%EF%BC%835%EF%BC%9AC++%E5%86%85%E5%AD%98%E7%AE%A1%E7%90%86/",
            "url": "https://www.starlinglin.top/computer-science/Cpp-programme-note/%E6%A4%8B%E9%B8%9FC++%E7%AC%94%E8%AE%B0%20%EF%BC%835%EF%BC%9AC++%E5%86%85%E5%AD%98%E7%AE%A1%E7%90%86/",
            "title": "椋鸟C++笔记#5：C++内存管理",
            "date_published": "2024-06-10T18:15:47.000Z",
            "content_html": "<div class=\"note warning\">\n<p>本系列暴死，不会更新了。</p>\n</div>\n<div class=\"note info\">\n<p>该系列为本人的学习笔记，主要由本人整理书写而成。部分内容来自教材、视频课程等，不能保证完全原创性。</p>\n</div>\n<p>萌新的学习笔记，写错了恳请斧正。</p>\n<h3 id=\"c语言中的动态内存管理\"><a class=\"anchor\" href=\"#c语言中的动态内存管理\">#</a> C 语言中的动态内存管理</h3>\n<p>C 语言中，我们使用 <code>malloc</code> 、 <code>calloc</code> 、 <code>realloc</code> 、 <code>free</code>  来动态管理内存。</p>\n<figure class=\"highlight c\"><figcaption data-lang=\"c\"></figcaption><table><tr><td data-num=\"1\"></td><td><pre><span class=\"token keyword\">int</span> <span class=\"token function\">main</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"2\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"3\"></td><td><pre>    <span class=\"token keyword\">int</span><span class=\"token operator\">*</span> p <span class=\"token operator\">=</span> <span class=\"token punctuation\">(</span><span class=\"token keyword\">int</span><span class=\"token operator\">*</span><span class=\"token punctuation\">)</span><span class=\"token function\">malloc</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">sizeof</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">int</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\t<span class=\"token comment\">// 动态开辟</span></pre></td></tr><tr><td data-num=\"4\"></td><td><pre>    <span class=\"token function\">free</span><span class=\"token punctuation\">(</span>p<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"5\"></td><td><pre>    <span class=\"token keyword\">int</span><span class=\"token operator\">*</span> q <span class=\"token operator\">=</span> <span class=\"token punctuation\">(</span><span class=\"token keyword\">int</span><span class=\"token operator\">*</span><span class=\"token punctuation\">)</span><span class=\"token function\">calloc</span><span class=\"token punctuation\">(</span><span class=\"token number\">4</span><span class=\"token punctuation\">,</span> <span class=\"token keyword\">sizeof</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">int</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\t<span class=\"token comment\">// 动态开辟并赋值</span></pre></td></tr><tr><td data-num=\"6\"></td><td><pre>    <span class=\"token keyword\">int</span><span class=\"token operator\">*</span> r <span class=\"token operator\">=</span> <span class=\"token punctuation\">(</span><span class=\"token keyword\">int</span><span class=\"token operator\">*</span><span class=\"token punctuation\">)</span><span class=\"token function\">realloc</span><span class=\"token punctuation\">(</span>q<span class=\"token punctuation\">,</span> <span class=\"token number\">10</span> <span class=\"token operator\">*</span> <span class=\"token keyword\">sizeof</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">int</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\t<span class=\"token comment\">// 重新分配空间</span></pre></td></tr><tr><td data-num=\"7\"></td><td><pre>    <span class=\"token function\">free</span><span class=\"token punctuation\">(</span>r<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"8\"></td><td><pre><span class=\"token punctuation\">&#125;</span></pre></td></tr></table></figure><h3 id=\"c中的动态内存管理\"><a class=\"anchor\" href=\"#c中的动态内存管理\">#</a> C++ 中的动态内存管理</h3>\n<p>C++ 中有更简单方便的内存管理方式，那就是使用 <code>new</code> 、 <code>delete</code>  来管理内存。</p>\n<h4 id=\"使用newdelete操作内置类型\"><a class=\"anchor\" href=\"#使用newdelete操作内置类型\">#</a> 使用 new/delete 操作内置类型</h4>\n<p><mark>注意：如果使用 new 开辟空间就用 delete 删除，如果使用 new [] 开辟数组就用 delete [] 删除。</mark></p>\n<ol>\n<li>\n<p>动态申请与删除一个内置类型变量的空间：</p>\n<figure class=\"highlight cpp\"><figcaption data-lang=\"C++\"></figcaption><table><tr><td data-num=\"1\"></td><td><pre><span class=\"token keyword\">int</span><span class=\"token operator\">*</span> pi <span class=\"token operator\">=</span> <span class=\"token keyword\">new</span> <span class=\"token keyword\">int</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"2\"></td><td><pre><span class=\"token keyword\">int</span><span class=\"token operator\">*</span> pf <span class=\"token operator\">=</span> <span class=\"token keyword\">new</span> <span class=\"token keyword\">float</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"3\"></td><td><pre><span class=\"token keyword\">int</span><span class=\"token operator\">*</span> pl <span class=\"token operator\">=</span> <span class=\"token keyword\">new</span> <span class=\"token keyword\">long</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"4\"></td><td><pre><span class=\"token keyword\">int</span><span class=\"token operator\">*</span> pb <span class=\"token operator\">=</span> <span class=\"token keyword\">new</span> <span class=\"token keyword\">bool</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"5\"></td><td><pre></pre></td></tr><tr><td data-num=\"6\"></td><td><pre><span class=\"token keyword\">delete</span> pi<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"7\"></td><td><pre><span class=\"token keyword\">delete</span> pf<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"8\"></td><td><pre><span class=\"token keyword\">delete</span> pl<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"9\"></td><td><pre><span class=\"token keyword\">delete</span> pb<span class=\"token punctuation\">;</span></pre></td></tr></table></figure></li>\n<li>\n<p>动态申请与删除一个内置类型变量的空间并完成初始化：</p>\n<figure class=\"highlight cpp\"><figcaption data-lang=\"C++\"></figcaption><table><tr><td data-num=\"1\"></td><td><pre><span class=\"token keyword\">int</span><span class=\"token operator\">*</span> pi <span class=\"token operator\">=</span> <span class=\"token keyword\">new</span> <span class=\"token keyword\">int</span><span class=\"token punctuation\">(</span><span class=\"token number\">114514</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"2\"></td><td><pre><span class=\"token keyword\">int</span><span class=\"token operator\">*</span> pf <span class=\"token operator\">=</span> <span class=\"token keyword\">new</span> <span class=\"token keyword\">float</span><span class=\"token punctuation\">(</span><span class=\"token number\">3.14f</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"3\"></td><td><pre><span class=\"token keyword\">int</span><span class=\"token operator\">*</span> pl <span class=\"token operator\">=</span> <span class=\"token keyword\">new</span> <span class=\"token keyword\">long</span><span class=\"token punctuation\">(</span><span class=\"token number\">1145141919810</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"4\"></td><td><pre><span class=\"token keyword\">int</span><span class=\"token operator\">*</span> pb <span class=\"token operator\">=</span> <span class=\"token keyword\">new</span> <span class=\"token keyword\">bool</span><span class=\"token punctuation\">(</span><span class=\"token boolean\">true</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"5\"></td><td><pre></pre></td></tr><tr><td data-num=\"6\"></td><td><pre><span class=\"token keyword\">delete</span> pi<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"7\"></td><td><pre><span class=\"token keyword\">delete</span> pf<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"8\"></td><td><pre><span class=\"token keyword\">delete</span> pl<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"9\"></td><td><pre><span class=\"token keyword\">delete</span> pb<span class=\"token punctuation\">;</span></pre></td></tr></table></figure></li>\n<li>\n<p>动态申请与删除内置类型变量<strong>数组</strong>的空间：</p>\n<figure class=\"highlight cpp\"><figcaption data-lang=\"C++\"></figcaption><table><tr><td data-num=\"1\"></td><td><pre><span class=\"token keyword\">int</span><span class=\"token operator\">*</span> pi <span class=\"token operator\">=</span> <span class=\"token keyword\">new</span> <span class=\"token keyword\">int</span><span class=\"token punctuation\">[</span><span class=\"token number\">5</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"2\"></td><td><pre><span class=\"token keyword\">int</span><span class=\"token operator\">*</span> pf <span class=\"token operator\">=</span> <span class=\"token keyword\">new</span> <span class=\"token keyword\">float</span><span class=\"token punctuation\">[</span><span class=\"token number\">5</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"3\"></td><td><pre><span class=\"token keyword\">int</span><span class=\"token operator\">*</span> pl <span class=\"token operator\">=</span> <span class=\"token keyword\">new</span> <span class=\"token keyword\">long</span><span class=\"token punctuation\">[</span><span class=\"token number\">5</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"4\"></td><td><pre><span class=\"token keyword\">int</span><span class=\"token operator\">*</span> pb <span class=\"token operator\">=</span> <span class=\"token keyword\">new</span> <span class=\"token keyword\">bool</span><span class=\"token punctuation\">[</span><span class=\"token number\">5</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"5\"></td><td><pre></pre></td></tr><tr><td data-num=\"6\"></td><td><pre><span class=\"token keyword\">delete</span><span class=\"token punctuation\">[</span><span class=\"token punctuation\">]</span> pi<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"7\"></td><td><pre><span class=\"token keyword\">delete</span><span class=\"token punctuation\">[</span><span class=\"token punctuation\">]</span> pf<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"8\"></td><td><pre><span class=\"token keyword\">delete</span><span class=\"token punctuation\">[</span><span class=\"token punctuation\">]</span> pl<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"9\"></td><td><pre><span class=\"token keyword\">delete</span><span class=\"token punctuation\">[</span><span class=\"token punctuation\">]</span> pb<span class=\"token punctuation\">;</span></pre></td></tr></table></figure></li>\n<li>\n<p>动态申请与删除内置类型变量<strong>数组</strong>的空间并完成初始化：</p>\n<figure class=\"highlight cpp\"><figcaption data-lang=\"C++\"></figcaption><table><tr><td data-num=\"1\"></td><td><pre><span class=\"token keyword\">int</span><span class=\"token operator\">*</span> pi <span class=\"token operator\">=</span> <span class=\"token keyword\">new</span> <span class=\"token keyword\">int</span><span class=\"token punctuation\">[</span><span class=\"token number\">5</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">&#123;</span><span class=\"token number\">1</span><span class=\"token punctuation\">,</span> <span class=\"token number\">2</span><span class=\"token punctuation\">,</span> <span class=\"token number\">3</span><span class=\"token punctuation\">,</span> <span class=\"token number\">4</span><span class=\"token punctuation\">,</span> <span class=\"token number\">5</span><span class=\"token punctuation\">&#125;</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"2\"></td><td><pre><span class=\"token keyword\">float</span><span class=\"token operator\">*</span> pf <span class=\"token operator\">=</span> <span class=\"token keyword\">new</span> <span class=\"token keyword\">float</span><span class=\"token punctuation\">[</span><span class=\"token number\">5</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">&#123;</span><span class=\"token number\">1.1f</span><span class=\"token punctuation\">,</span> <span class=\"token number\">2.2f</span><span class=\"token punctuation\">,</span> <span class=\"token number\">3.3f</span><span class=\"token punctuation\">,</span> <span class=\"token number\">4.4f</span><span class=\"token punctuation\">,</span> <span class=\"token number\">5.5f</span><span class=\"token punctuation\">&#125;</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"3\"></td><td><pre><span class=\"token keyword\">long</span><span class=\"token operator\">*</span> pl <span class=\"token operator\">=</span> <span class=\"token keyword\">new</span> <span class=\"token keyword\">long</span><span class=\"token punctuation\">[</span><span class=\"token number\">5</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">&#123;</span><span class=\"token number\">10</span><span class=\"token punctuation\">,</span> <span class=\"token number\">20</span><span class=\"token punctuation\">,</span> <span class=\"token number\">30</span><span class=\"token punctuation\">,</span> <span class=\"token number\">40</span><span class=\"token punctuation\">,</span> <span class=\"token number\">50</span><span class=\"token punctuation\">&#125;</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"4\"></td><td><pre><span class=\"token keyword\">bool</span><span class=\"token operator\">*</span> pb <span class=\"token operator\">=</span> <span class=\"token keyword\">new</span> <span class=\"token keyword\">bool</span><span class=\"token punctuation\">[</span><span class=\"token number\">5</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">&#123;</span><span class=\"token boolean\">true</span><span class=\"token punctuation\">,</span> <span class=\"token boolean\">false</span><span class=\"token punctuation\">,</span> <span class=\"token boolean\">true</span><span class=\"token punctuation\">,</span> <span class=\"token boolean\">false</span><span class=\"token punctuation\">,</span> <span class=\"token boolean\">true</span><span class=\"token punctuation\">&#125;</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"5\"></td><td><pre></pre></td></tr><tr><td data-num=\"6\"></td><td><pre><span class=\"token keyword\">delete</span><span class=\"token punctuation\">[</span><span class=\"token punctuation\">]</span> pi<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"7\"></td><td><pre><span class=\"token keyword\">delete</span><span class=\"token punctuation\">[</span><span class=\"token punctuation\">]</span> pf<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"8\"></td><td><pre><span class=\"token keyword\">delete</span><span class=\"token punctuation\">[</span><span class=\"token punctuation\">]</span> pl<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"9\"></td><td><pre><span class=\"token keyword\">delete</span><span class=\"token punctuation\">[</span><span class=\"token punctuation\">]</span> pb<span class=\"token punctuation\">;</span></pre></td></tr></table></figure></li>\n</ol>\n<h4 id=\"使用newdelete操作自定义类型\"><a class=\"anchor\" href=\"#使用newdelete操作自定义类型\">#</a> 使用 new/delete 操作自定义类型</h4>\n<p>这与自定义类型区别主要在于：<mark>使用 new/delete 操作自定义类型时会自动调用自定义类型的构造 / 析构函数。</mark></p>\n<figure class=\"highlight cpp\"><figcaption data-lang=\"C++\"></figcaption><table><tr><td data-num=\"1\"></td><td><pre><span class=\"token keyword\">class</span> <span class=\"token class-name\">A</span></pre></td></tr><tr><td data-num=\"2\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"3\"></td><td><pre><span class=\"token keyword\">public</span><span class=\"token operator\">:</span></pre></td></tr><tr><td data-num=\"4\"></td><td><pre>    <span class=\"token function\">A</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">int</span> a <span class=\"token operator\">=</span> <span class=\"token number\">0</span><span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"5\"></td><td><pre>        <span class=\"token operator\">:</span> <span class=\"token function\">m_a</span><span class=\"token punctuation\">(</span>a<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"6\"></td><td><pre>    <span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"7\"></td><td><pre>        cout <span class=\"token operator\">&lt;&lt;</span> <span class=\"token string\">\"A\"</span> <span class=\"token operator\">&lt;&lt;</span> endl<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"8\"></td><td><pre>    <span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"9\"></td><td><pre>    </pre></td></tr><tr><td data-num=\"10\"></td><td><pre>    <span class=\"token operator\">~</span><span class=\"token function\">A</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"11\"></td><td><pre>    <span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"12\"></td><td><pre>        cout <span class=\"token operator\">&lt;&lt;</span> <span class=\"token string\">\"~A\"</span> <span class=\"token operator\">&lt;&lt;</span> endl<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"13\"></td><td><pre>    <span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"14\"></td><td><pre>    </pre></td></tr><tr><td data-num=\"15\"></td><td><pre><span class=\"token keyword\">private</span><span class=\"token operator\">:</span></pre></td></tr><tr><td data-num=\"16\"></td><td><pre>    <span class=\"token keyword\">int</span> m_a<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"17\"></td><td><pre><span class=\"token punctuation\">&#125;</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"18\"></td><td><pre></pre></td></tr><tr><td data-num=\"19\"></td><td><pre><span class=\"token keyword\">int</span> <span class=\"token function\">main</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"20\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"21\"></td><td><pre>    A<span class=\"token operator\">*</span> oA <span class=\"token operator\">=</span> <span class=\"token keyword\">new</span> A<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"22\"></td><td><pre>    <span class=\"token keyword\">delete</span> oA<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"23\"></td><td><pre>    A<span class=\"token operator\">*</span> oB <span class=\"token operator\">=</span> <span class=\"token punctuation\">(</span>A<span class=\"token operator\">*</span><span class=\"token punctuation\">)</span><span class=\"token function\">malloc</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">sizeof</span><span class=\"token punctuation\">(</span>A<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"24\"></td><td><pre>    <span class=\"token function\">free</span><span class=\"token punctuation\">(</span>oB<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"25\"></td><td><pre>    </pre></td></tr><tr><td data-num=\"26\"></td><td><pre>    <span class=\"token keyword\">return</span> <span class=\"token number\">0</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"27\"></td><td><pre><span class=\"token punctuation\">&#125;</span></pre></td></tr></table></figure><p>该程序运行结果为：</p>\n<figure class=\"highlight bash\"><figcaption data-lang=\"bash\"></figcaption><table><tr><td data-num=\"1\"></td><td><pre>A</pre></td></tr><tr><td data-num=\"2\"></td><td><pre>~A</pre></td></tr></table></figure><h4 id=\"operator-newoperator-new与operator-deleteoperator-delete函数\"><a class=\"anchor\" href=\"#operator-newoperator-new与operator-deleteoperator-delete函数\">#</a> operator new (operator new []) 与 operator delete (operator delete []) 函数</h4>\n<p>看到 operator new 和 operator delete，很多人会以为这是 new 与 delete 的重载函数。</p>\n<p>但是，<mark>operator new 和 operator delete 不能理解为是 new 与 delete 的重载函数！</mark></p>\n<p>operator new 与 operator delete 其实是系统提供的全局函数，而 new 和 delete 在底层其实就是调用了这两个函数来实现的。</p>\n<p><mark>以下给出的函数定义随编译器不同有所变化！</mark></p>\n<h5 id=\"operator-new函数\"><a class=\"anchor\" href=\"#operator-new函数\">#</a> operator new 函数</h5>\n<figure class=\"highlight cpp\"><figcaption data-lang=\"C++\"></figcaption><table><tr><td data-num=\"1\"></td><td><pre><span class=\"token keyword\">void</span><span class=\"token operator\">*</span> <span class=\"token keyword\">operator</span> <span class=\"token keyword\">new</span><span class=\"token punctuation\">(</span>std<span class=\"token double-colon punctuation\">::</span>size_t size<span class=\"token punctuation\">)</span> </pre></td></tr><tr><td data-num=\"2\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"3\"></td><td><pre>    <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>size <span class=\"token operator\">==</span> <span class=\"token number\">0</span><span class=\"token punctuation\">)</span>\t<span class=\"token comment\">// 如果请求的大小为 0，分配至少一个字节</span></pre></td></tr><tr><td data-num=\"4\"></td><td><pre>    <span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"5\"></td><td><pre>        size <span class=\"token operator\">=</span> <span class=\"token number\">1</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"6\"></td><td><pre>    <span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"7\"></td><td><pre>    <span class=\"token keyword\">while</span> <span class=\"token punctuation\">(</span><span class=\"token boolean\">true</span><span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"8\"></td><td><pre>    <span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"9\"></td><td><pre>        <span class=\"token keyword\">void</span><span class=\"token operator\">*</span> p <span class=\"token operator\">=</span> std<span class=\"token double-colon punctuation\">::</span><span class=\"token function\">malloc</span><span class=\"token punctuation\">(</span>size<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>  <span class=\"token comment\">// 使用 malloc 分配内存</span></pre></td></tr><tr><td data-num=\"10\"></td><td><pre>        <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>p<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"11\"></td><td><pre>            <span class=\"token keyword\">return</span> p<span class=\"token punctuation\">;</span>  <span class=\"token comment\">// 如果分配成功，返回指针</span></pre></td></tr><tr><td data-num=\"12\"></td><td><pre>        <span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"13\"></td><td><pre>        std<span class=\"token double-colon punctuation\">::</span>new_handler handler <span class=\"token operator\">=</span> std<span class=\"token double-colon punctuation\">::</span><span class=\"token function\">get_new_handler</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>  <span class=\"token comment\">// 获取当前的 new_handler</span></pre></td></tr><tr><td data-num=\"14\"></td><td><pre>        <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span><span class=\"token operator\">!</span>handler<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"15\"></td><td><pre>            <span class=\"token keyword\">throw</span> std<span class=\"token double-colon punctuation\">::</span><span class=\"token function\">bad_alloc</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>  <span class=\"token comment\">// 如果没有设置 new_handler，抛出 bad_alloc 异常</span></pre></td></tr><tr><td data-num=\"16\"></td><td><pre>        <span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"17\"></td><td><pre>        <span class=\"token function\">handler</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>  <span class=\"token comment\">// 调用 new_handler</span></pre></td></tr><tr><td data-num=\"18\"></td><td><pre>    <span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"19\"></td><td><pre><span class=\"token punctuation\">&#125;</span></pre></td></tr></table></figure><h5 id=\"operator-delete函数\"><a class=\"anchor\" href=\"#operator-delete函数\">#</a> operator delete 函数</h5>\n<figure class=\"highlight cpp\"><figcaption data-lang=\"C++\"></figcaption><table><tr><td data-num=\"1\"></td><td><pre><span class=\"token keyword\">void</span> <span class=\"token keyword\">operator</span> <span class=\"token keyword\">delete</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">void</span><span class=\"token operator\">*</span> ptr<span class=\"token punctuation\">)</span> <span class=\"token keyword\">noexcept</span>\t<span class=\"token comment\">//noexcept 说明此函数不会抛出异常</span></pre></td></tr><tr><td data-num=\"2\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"3\"></td><td><pre>    std<span class=\"token double-colon punctuation\">::</span><span class=\"token function\">free</span><span class=\"token punctuation\">(</span>ptr<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>  <span class=\"token comment\">// 使用 free 释放内存</span></pre></td></tr><tr><td data-num=\"4\"></td><td><pre><span class=\"token punctuation\">&#125;</span></pre></td></tr></table></figure><h5 id=\"operator-new和operator-delete\"><a class=\"anchor\" href=\"#operator-new和operator-delete\">#</a> operator new [] 和 operator delete []</h5>\n<p>同样的，new [] 和 delete [] 在底层调用的是 operator new [] 和 operator delete [] 函数。</p>\n<figure class=\"highlight cpp\"><figcaption data-lang=\"C++\"></figcaption><table><tr><td data-num=\"1\"></td><td><pre><span class=\"token keyword\">void</span><span class=\"token operator\">*</span> <span class=\"token keyword\">operator</span> <span class=\"token keyword\">new</span><span class=\"token punctuation\">[</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">(</span>std<span class=\"token double-colon punctuation\">::</span>size_t size<span class=\"token punctuation\">)</span> </pre></td></tr><tr><td data-num=\"2\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"3\"></td><td><pre>    <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>size <span class=\"token operator\">==</span> <span class=\"token number\">0</span><span class=\"token punctuation\">)</span> </pre></td></tr><tr><td data-num=\"4\"></td><td><pre>    <span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"5\"></td><td><pre>        size <span class=\"token operator\">=</span> <span class=\"token number\">1</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"6\"></td><td><pre>    <span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"7\"></td><td><pre>    <span class=\"token keyword\">while</span> <span class=\"token punctuation\">(</span><span class=\"token boolean\">true</span><span class=\"token punctuation\">)</span> </pre></td></tr><tr><td data-num=\"8\"></td><td><pre>    <span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"9\"></td><td><pre>        <span class=\"token keyword\">void</span><span class=\"token operator\">*</span> p <span class=\"token operator\">=</span> std<span class=\"token double-colon punctuation\">::</span><span class=\"token function\">malloc</span><span class=\"token punctuation\">(</span>size<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"10\"></td><td><pre>        <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>p<span class=\"token punctuation\">)</span> </pre></td></tr><tr><td data-num=\"11\"></td><td><pre>        <span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"12\"></td><td><pre>            <span class=\"token keyword\">return</span> p<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"13\"></td><td><pre>        <span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"14\"></td><td><pre>        std<span class=\"token double-colon punctuation\">::</span>new_handler handler <span class=\"token operator\">=</span> std<span class=\"token double-colon punctuation\">::</span><span class=\"token function\">get_new_handler</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"15\"></td><td><pre>        <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span><span class=\"token operator\">!</span>handler<span class=\"token punctuation\">)</span> </pre></td></tr><tr><td data-num=\"16\"></td><td><pre>        <span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"17\"></td><td><pre>            <span class=\"token keyword\">throw</span> std<span class=\"token double-colon punctuation\">::</span><span class=\"token function\">bad_alloc</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"18\"></td><td><pre>        <span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"19\"></td><td><pre>        <span class=\"token function\">handler</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"20\"></td><td><pre>    <span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"21\"></td><td><pre><span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"22\"></td><td><pre></pre></td></tr><tr><td data-num=\"23\"></td><td><pre><span class=\"token keyword\">void</span> <span class=\"token keyword\">operator</span> <span class=\"token keyword\">delete</span><span class=\"token punctuation\">[</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">void</span><span class=\"token operator\">*</span> ptr<span class=\"token punctuation\">)</span> <span class=\"token keyword\">noexcept</span> </pre></td></tr><tr><td data-num=\"24\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"25\"></td><td><pre>    std<span class=\"token double-colon punctuation\">::</span><span class=\"token function\">free</span><span class=\"token punctuation\">(</span>ptr<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"26\"></td><td><pre><span class=\"token punctuation\">&#125;</span></pre></td></tr></table></figure><h4 id=\"new与delete的实现原理\"><a class=\"anchor\" href=\"#new与delete的实现原理\">#</a> new 与 delete 的实现原理</h4>\n<p>如果申请的是<strong>内置类型</strong>的空间，new 和 malloc、delete 和 free 基本类似。</p>\n<p>不同的是：</p>\n<ol>\n<li>new/delete 申请和释放的是单个元素的空间，new [] 和 delete [] 申请的是<strong>连续空间</strong>。</li>\n<li>new 在申请空间失败时会抛异常；malloc 会返回 NULL。</li>\n</ol>\n<p>对于自定义类型：</p>\n<ol>\n<li>new 的原理：\n<ul>\n<li>调用 operator new 函数申请空间。</li>\n<li>执行构造函数。</li>\n</ul>\n</li>\n<li>delete 的原理：\n<ul>\n<li>执行析构函数。</li>\n<li>调用 operator delete 函数释放空间。</li>\n</ul>\n</li>\n<li>new [] 的原理：\n<ul>\n<li>调用 operator new [] 函数申请空间。</li>\n<li>分别执行构造函数。</li>\n<li><strong>在这片空间前紧挨的位置申请 4 个字节用于保存 N。</strong></li>\n</ul>\n</li>\n<li>delete [] 的原理：\n<ul>\n<li><strong>往前读取 4 个字节，获得 N。</strong></li>\n<li>N 个元素分别执行析构函数。</li>\n<li>调用 operator delete [] 函数释放空间。</li>\n</ul>\n</li>\n</ol>\n<h4 id=\"定位new表达式placement-new\"><a class=\"anchor\" href=\"#定位new表达式placement-new\">#</a> 定位 new 表达式（placement-new）</h4>\n<p>我们可以直接通过指针显式的调用析构函数：</p>\n<figure class=\"highlight cpp\"><figcaption data-lang=\"C++\"></figcaption><table><tr><td data-num=\"1\"></td><td><pre><span class=\"token macro property\"><span class=\"token directive-hash\">#</span><span class=\"token directive keyword\">include</span> <span class=\"token string\">&lt;iostream></span></span></pre></td></tr><tr><td data-num=\"2\"></td><td><pre></pre></td></tr><tr><td data-num=\"3\"></td><td><pre><span class=\"token keyword\">using</span> <span class=\"token keyword\">namespace</span> std<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"4\"></td><td><pre></pre></td></tr><tr><td data-num=\"5\"></td><td><pre><span class=\"token keyword\">class</span> <span class=\"token class-name\">A</span></pre></td></tr><tr><td data-num=\"6\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"7\"></td><td><pre><span class=\"token keyword\">public</span><span class=\"token operator\">:</span></pre></td></tr><tr><td data-num=\"8\"></td><td><pre>\t<span class=\"token function\">A</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">int</span> a <span class=\"token operator\">=</span> <span class=\"token number\">0</span><span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"9\"></td><td><pre>\t\t<span class=\"token operator\">:</span> <span class=\"token function\">m_a</span><span class=\"token punctuation\">(</span>a<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"10\"></td><td><pre>\t<span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"11\"></td><td><pre>\t\tcout <span class=\"token operator\">&lt;&lt;</span> <span class=\"token string\">\"A()\"</span> <span class=\"token operator\">&lt;&lt;</span> <span class=\"token keyword\">this</span> <span class=\"token operator\">&lt;&lt;</span> endl<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"12\"></td><td><pre>\t<span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"13\"></td><td><pre></pre></td></tr><tr><td data-num=\"14\"></td><td><pre>\t<span class=\"token operator\">~</span><span class=\"token function\">A</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"15\"></td><td><pre>\t<span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"16\"></td><td><pre>\t\tcout <span class=\"token operator\">&lt;&lt;</span> <span class=\"token string\">\"~A()\"</span> <span class=\"token operator\">&lt;&lt;</span> <span class=\"token keyword\">this</span> <span class=\"token operator\">&lt;&lt;</span> endl<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"17\"></td><td><pre>\t<span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"18\"></td><td><pre></pre></td></tr><tr><td data-num=\"19\"></td><td><pre><span class=\"token keyword\">private</span><span class=\"token operator\">:</span></pre></td></tr><tr><td data-num=\"20\"></td><td><pre>\t<span class=\"token keyword\">int</span> m_a<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"21\"></td><td><pre><span class=\"token punctuation\">&#125;</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"22\"></td><td><pre></pre></td></tr><tr><td data-num=\"23\"></td><td><pre><span class=\"token keyword\">int</span> <span class=\"token function\">main</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"24\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"25\"></td><td><pre>\tA<span class=\"token operator\">*</span> p1 <span class=\"token operator\">=</span> <span class=\"token keyword\">new</span> A<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"26\"></td><td><pre>\tp1<span class=\"token operator\">-></span><span class=\"token operator\">~</span><span class=\"token function\">A</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"27\"></td><td><pre>\t<span class=\"token function\">free</span><span class=\"token punctuation\">(</span>p1<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"28\"></td><td><pre></pre></td></tr><tr><td data-num=\"29\"></td><td><pre>\t<span class=\"token keyword\">return</span> <span class=\"token number\">0</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"30\"></td><td><pre><span class=\"token punctuation\">&#125;</span></pre></td></tr></table></figure><p><strong>那我们能直接显式调用构造函数吗？答案是否定的。</strong></p>\n<p>但是我们可以使用<strong>定位 new 表达式</strong>：</p>\n<figure class=\"highlight cpp\"><figcaption data-lang=\"C++\"></figcaption><table><tr><td data-num=\"1\"></td><td><pre><span class=\"token macro property\"><span class=\"token directive-hash\">#</span><span class=\"token directive keyword\">include</span> <span class=\"token string\">&lt;iostream></span></span></pre></td></tr><tr><td data-num=\"2\"></td><td><pre></pre></td></tr><tr><td data-num=\"3\"></td><td><pre><span class=\"token keyword\">using</span> <span class=\"token keyword\">namespace</span> std<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"4\"></td><td><pre></pre></td></tr><tr><td data-num=\"5\"></td><td><pre><span class=\"token keyword\">class</span> <span class=\"token class-name\">A</span></pre></td></tr><tr><td data-num=\"6\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"7\"></td><td><pre><span class=\"token keyword\">public</span><span class=\"token operator\">:</span></pre></td></tr><tr><td data-num=\"8\"></td><td><pre>\t<span class=\"token function\">A</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">int</span> a <span class=\"token operator\">=</span> <span class=\"token number\">0</span><span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"9\"></td><td><pre>\t\t<span class=\"token operator\">:</span> <span class=\"token function\">m_a</span><span class=\"token punctuation\">(</span>a<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"10\"></td><td><pre>\t<span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"11\"></td><td><pre>\t\tcout <span class=\"token operator\">&lt;&lt;</span> <span class=\"token string\">\"A()\"</span> <span class=\"token operator\">&lt;&lt;</span> <span class=\"token keyword\">this</span> <span class=\"token operator\">&lt;&lt;</span> endl<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"12\"></td><td><pre>\t<span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"13\"></td><td><pre></pre></td></tr><tr><td data-num=\"14\"></td><td><pre>\t<span class=\"token operator\">~</span><span class=\"token function\">A</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"15\"></td><td><pre>\t<span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"16\"></td><td><pre>\t\tcout <span class=\"token operator\">&lt;&lt;</span> <span class=\"token string\">\"~A()\"</span> <span class=\"token operator\">&lt;&lt;</span> <span class=\"token keyword\">this</span> <span class=\"token operator\">&lt;&lt;</span> endl<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"17\"></td><td><pre>\t<span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"18\"></td><td><pre></pre></td></tr><tr><td data-num=\"19\"></td><td><pre><span class=\"token keyword\">private</span><span class=\"token operator\">:</span></pre></td></tr><tr><td data-num=\"20\"></td><td><pre>\t<span class=\"token keyword\">int</span> m_a<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"21\"></td><td><pre><span class=\"token punctuation\">&#125;</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"22\"></td><td><pre></pre></td></tr><tr><td data-num=\"23\"></td><td><pre><span class=\"token keyword\">int</span> <span class=\"token function\">main</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"24\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"25\"></td><td><pre>\tA<span class=\"token operator\">*</span> p1 <span class=\"token operator\">=</span> <span class=\"token punctuation\">(</span>A<span class=\"token operator\">*</span><span class=\"token punctuation\">)</span><span class=\"token function\">malloc</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">sizeof</span><span class=\"token punctuation\">(</span>A<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"26\"></td><td><pre>\t<span class=\"token keyword\">new</span> <span class=\"token punctuation\">(</span>p1<span class=\"token punctuation\">)</span> A<span class=\"token punctuation\">;</span>\t<span class=\"token comment\">// 在地址 p1 处执行类 A 的构造函数</span></pre></td></tr><tr><td data-num=\"27\"></td><td><pre>\tp1<span class=\"token operator\">-></span><span class=\"token operator\">~</span><span class=\"token function\">A</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"28\"></td><td><pre>\t<span class=\"token function\">free</span><span class=\"token punctuation\">(</span>p1<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"29\"></td><td><pre></pre></td></tr><tr><td data-num=\"30\"></td><td><pre>\t<span class=\"token keyword\">return</span> <span class=\"token number\">0</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"31\"></td><td><pre><span class=\"token punctuation\">&#125;</span></pre></td></tr></table></figure><p>其结构就是 <code>new</code>  加上 <code>(这里放地址)</code>  加上 <code>类名</code> 。</p>\n<p>或者也可以同时初始化：</p>\n<figure class=\"highlight cpp\"><figcaption data-lang=\"C++\"></figcaption><table><tr><td data-num=\"1\"></td><td><pre><span class=\"token keyword\">int</span> <span class=\"token function\">main</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"2\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"3\"></td><td><pre>\tA<span class=\"token operator\">*</span> p1 <span class=\"token operator\">=</span> <span class=\"token punctuation\">(</span>A<span class=\"token operator\">*</span><span class=\"token punctuation\">)</span><span class=\"token function\">malloc</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">sizeof</span><span class=\"token punctuation\">(</span>A<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"4\"></td><td><pre>\t<span class=\"token keyword\">new</span> <span class=\"token punctuation\">(</span>p1<span class=\"token punctuation\">)</span> <span class=\"token function\">A</span> <span class=\"token punctuation\">(</span><span class=\"token number\">10</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\t<span class=\"token comment\">// 在地址 p1 处执行类 A 的构造函数并初始化为 10</span></pre></td></tr><tr><td data-num=\"5\"></td><td><pre>\tp1<span class=\"token operator\">-></span><span class=\"token operator\">~</span><span class=\"token function\">A</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"6\"></td><td><pre>\t<span class=\"token function\">free</span><span class=\"token punctuation\">(</span>p1<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"7\"></td><td><pre></pre></td></tr><tr><td data-num=\"8\"></td><td><pre>\t<span class=\"token keyword\">return</span> <span class=\"token number\">0</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"9\"></td><td><pre><span class=\"token punctuation\">&#125;</span></pre></td></tr></table></figure><p>当然我们也能显示的调用 operator new (operator new []) 与 operator delete (operator delete []) 函数：</p>\n<figure class=\"highlight cpp\"><figcaption data-lang=\"C++\"></figcaption><table><tr><td data-num=\"1\"></td><td><pre><span class=\"token macro property\"><span class=\"token directive-hash\">#</span><span class=\"token directive keyword\">include</span> <span class=\"token string\">&lt;iostream></span></span></pre></td></tr><tr><td data-num=\"2\"></td><td><pre></pre></td></tr><tr><td data-num=\"3\"></td><td><pre><span class=\"token keyword\">using</span> <span class=\"token keyword\">namespace</span> std<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"4\"></td><td><pre></pre></td></tr><tr><td data-num=\"5\"></td><td><pre><span class=\"token keyword\">class</span> <span class=\"token class-name\">A</span></pre></td></tr><tr><td data-num=\"6\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"7\"></td><td><pre><span class=\"token keyword\">public</span><span class=\"token operator\">:</span></pre></td></tr><tr><td data-num=\"8\"></td><td><pre>\t<span class=\"token function\">A</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">int</span> a <span class=\"token operator\">=</span> <span class=\"token number\">0</span><span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"9\"></td><td><pre>\t\t<span class=\"token operator\">:</span> <span class=\"token function\">m_a</span><span class=\"token punctuation\">(</span>a<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"10\"></td><td><pre>\t<span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"11\"></td><td><pre>\t\tcout <span class=\"token operator\">&lt;&lt;</span> <span class=\"token string\">\"A()\"</span> <span class=\"token operator\">&lt;&lt;</span> <span class=\"token keyword\">this</span> <span class=\"token operator\">&lt;&lt;</span> endl<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"12\"></td><td><pre>\t<span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"13\"></td><td><pre></pre></td></tr><tr><td data-num=\"14\"></td><td><pre>\t<span class=\"token operator\">~</span><span class=\"token function\">A</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"15\"></td><td><pre>\t<span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"16\"></td><td><pre>\t\tcout <span class=\"token operator\">&lt;&lt;</span> <span class=\"token string\">\"~A()\"</span> <span class=\"token operator\">&lt;&lt;</span> <span class=\"token keyword\">this</span> <span class=\"token operator\">&lt;&lt;</span> endl<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"17\"></td><td><pre>\t<span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"18\"></td><td><pre></pre></td></tr><tr><td data-num=\"19\"></td><td><pre><span class=\"token keyword\">private</span><span class=\"token operator\">:</span></pre></td></tr><tr><td data-num=\"20\"></td><td><pre>\t<span class=\"token keyword\">int</span> m_a<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"21\"></td><td><pre><span class=\"token punctuation\">&#125;</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"22\"></td><td><pre></pre></td></tr><tr><td data-num=\"23\"></td><td><pre><span class=\"token keyword\">int</span> <span class=\"token function\">main</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"24\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"25\"></td><td><pre>\tA<span class=\"token operator\">*</span> p1 <span class=\"token operator\">=</span> <span class=\"token punctuation\">(</span>A<span class=\"token operator\">*</span><span class=\"token punctuation\">)</span><span class=\"token function\">malloc</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">sizeof</span><span class=\"token punctuation\">(</span>A<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"26\"></td><td><pre>\t<span class=\"token keyword\">new</span> <span class=\"token punctuation\">(</span>p1<span class=\"token punctuation\">)</span> A<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"27\"></td><td><pre>\tp1<span class=\"token operator\">-></span><span class=\"token operator\">~</span><span class=\"token function\">A</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"28\"></td><td><pre>\t<span class=\"token function\">free</span><span class=\"token punctuation\">(</span>p1<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"29\"></td><td><pre></pre></td></tr><tr><td data-num=\"30\"></td><td><pre>\tA<span class=\"token operator\">*</span> p2 <span class=\"token operator\">=</span> <span class=\"token punctuation\">(</span>A<span class=\"token operator\">*</span><span class=\"token punctuation\">)</span><span class=\"token keyword\">operator</span> <span class=\"token keyword\">new</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">sizeof</span><span class=\"token punctuation\">(</span>A<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"31\"></td><td><pre>\t<span class=\"token keyword\">new</span> <span class=\"token punctuation\">(</span>p2<span class=\"token punctuation\">)</span> <span class=\"token function\">A</span><span class=\"token punctuation\">(</span><span class=\"token number\">10</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"32\"></td><td><pre>\tp2<span class=\"token operator\">-></span><span class=\"token operator\">~</span><span class=\"token function\">A</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"33\"></td><td><pre>\t<span class=\"token keyword\">operator</span> <span class=\"token keyword\">delete</span><span class=\"token punctuation\">(</span>p2<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"34\"></td><td><pre></pre></td></tr><tr><td data-num=\"35\"></td><td><pre>\t<span class=\"token keyword\">return</span> <span class=\"token number\">0</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"36\"></td><td><pre><span class=\"token punctuation\">&#125;</span></pre></td></tr></table></figure><h3 id=\"检测内存泄露\"><a class=\"anchor\" href=\"#检测内存泄露\">#</a> 检测内存泄露</h3>\n<p>在 Visual Stodio 中我们可以使用 <code>_CrtDumpMemoryLeaks()</code>  函数来检测内存泄露，如果发生内存泄露这个函数会在输出窗口给出提示。</p>\n<figure class=\"highlight cpp\"><figcaption data-lang=\"C++\"></figcaption><table><tr><td data-num=\"1\"></td><td><pre><span class=\"token macro property\"><span class=\"token directive-hash\">#</span><span class=\"token directive keyword\">include</span> <span class=\"token string\">&lt;iostream></span></span></pre></td></tr><tr><td data-num=\"2\"></td><td><pre></pre></td></tr><tr><td data-num=\"3\"></td><td><pre><span class=\"token keyword\">using</span> <span class=\"token keyword\">namespace</span> std<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"4\"></td><td><pre></pre></td></tr><tr><td data-num=\"5\"></td><td><pre><span class=\"token keyword\">int</span> <span class=\"token function\">main</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"6\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"7\"></td><td><pre>\t<span class=\"token keyword\">int</span><span class=\"token operator\">*</span> p <span class=\"token operator\">=</span> <span class=\"token keyword\">new</span> <span class=\"token keyword\">int</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"8\"></td><td><pre></pre></td></tr><tr><td data-num=\"9\"></td><td><pre>\t<span class=\"token function\">_CrtDumpMemoryLeaks</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"10\"></td><td><pre>\t<span class=\"token keyword\">return</span> <span class=\"token number\">0</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"11\"></td><td><pre><span class=\"token punctuation\">&#125;</span></pre></td></tr></table></figure><p>执行这段代码，我们可以在来源为调试的输出看到如下内容：</p>\n<figure class=\"highlight bash\"><figcaption data-lang=\"bash\"></figcaption><table><tr><td data-num=\"1\"></td><td><pre>Detected memory leaks<span class=\"token operator\">!</span></pre></td></tr><tr><td data-num=\"2\"></td><td><pre>Dumping objects -<span class=\"token operator\">></span></pre></td></tr><tr><td data-num=\"3\"></td><td><pre><span class=\"token punctuation\">&#123;</span><span class=\"token number\">81</span><span class=\"token punctuation\">&#125;</span> normal block at 0x00000221287C7400, <span class=\"token number\">4</span> bytes long.</pre></td></tr><tr><td data-num=\"4\"></td><td><pre> Data: <span class=\"token operator\">&lt;</span>    <span class=\"token operator\">></span> CD CD CD CD </pre></td></tr><tr><td data-num=\"5\"></td><td><pre>Object dump complete.</pre></td></tr></table></figure>",
            "tags": [
                "计算机科学",
                "C++笔记",
                "C++",
                "内存"
            ]
        },
        {
            "id": "https://www.starlinglin.top/computer-science/Cpp-programme-note/%E6%A4%8B%E9%B8%9FC++%E7%AC%94%E8%AE%B0%20%EF%BC%834%EF%BC%9A%E7%B1%BB%E7%9A%84%E5%88%9D%E5%A7%8B%E5%8C%96%E4%B8%8E%E5%B0%81%E8%A3%85/",
            "url": "https://www.starlinglin.top/computer-science/Cpp-programme-note/%E6%A4%8B%E9%B8%9FC++%E7%AC%94%E8%AE%B0%20%EF%BC%834%EF%BC%9A%E7%B1%BB%E7%9A%84%E5%88%9D%E5%A7%8B%E5%8C%96%E4%B8%8E%E5%B0%81%E8%A3%85/",
            "title": "椋鸟C++笔记#4：类的初始化与封装",
            "date_published": "2024-05-30T12:00:00.000Z",
            "content_html": "<div class=\"note warning\">\n<p>本系列暴死，不会更新了。</p>\n</div>\n<div class=\"note info\">\n<p>该系列为本人的学习笔记，主要由本人整理书写而成。部分内容来自教材、视频课程等，不能保证完全原创性。</p>\n</div>\n<p>萌新的学习笔记，写错了恳请斧正。</p>\n<h3 id=\"初始化列表\"><a class=\"anchor\" href=\"#初始化列表\">#</a> 初始化列表</h3>\n<p>在类的构造函数的函数名后可以加上这么一串结构，称之为<strong>初始化列表</strong>：</p>\n<figure class=\"highlight cpp\"><figcaption data-lang=\"C++\"></figcaption><table><tr><td data-num=\"1\"></td><td><pre><span class=\"token keyword\">class</span> <span class=\"token class-name\">Date</span></pre></td></tr><tr><td data-num=\"2\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"3\"></td><td><pre><span class=\"token keyword\">public</span><span class=\"token operator\">:</span></pre></td></tr><tr><td data-num=\"4\"></td><td><pre>    <span class=\"token function\">Date</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">int</span> year<span class=\"token punctuation\">,</span> <span class=\"token keyword\">int</span> month<span class=\"token punctuation\">,</span> <span class=\"token keyword\">int</span> day<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"5\"></td><td><pre>        <span class=\"token operator\">:</span> <span class=\"token function\">m_year</span><span class=\"token punctuation\">(</span>year<span class=\"token punctuation\">)</span>\t\t<span class=\"token comment\">// 定义与初始化</span></pre></td></tr><tr><td data-num=\"6\"></td><td><pre>        <span class=\"token punctuation\">,</span> <span class=\"token function\">m_month</span><span class=\"token punctuation\">(</span>month<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"7\"></td><td><pre>        <span class=\"token punctuation\">,</span> <span class=\"token function\">m_day</span><span class=\"token punctuation\">(</span>day<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"8\"></td><td><pre>    <span class=\"token punctuation\">&#123;</span><span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"9\"></td><td><pre>    </pre></td></tr><tr><td data-num=\"10\"></td><td><pre>    <span class=\"token function\">Date</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">int</span> year<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"11\"></td><td><pre>        <span class=\"token operator\">:</span> <span class=\"token function\">m_year</span><span class=\"token punctuation\">(</span>year<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"12\"></td><td><pre>        <span class=\"token punctuation\">,</span> <span class=\"token function\">m_month</span><span class=\"token punctuation\">(</span><span class=\"token number\">1</span><span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"13\"></td><td><pre>        <span class=\"token punctuation\">,</span> <span class=\"token function\">m_day</span><span class=\"token punctuation\">(</span><span class=\"token number\">1</span><span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"14\"></td><td><pre>    <span class=\"token punctuation\">&#123;</span><span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"15\"></td><td><pre>    </pre></td></tr><tr><td data-num=\"16\"></td><td><pre><span class=\"token keyword\">private</span><span class=\"token operator\">:</span></pre></td></tr><tr><td data-num=\"17\"></td><td><pre>    <span class=\"token keyword\">int</span> m_year<span class=\"token punctuation\">;</span>\t\t<span class=\"token comment\">// 声明</span></pre></td></tr><tr><td data-num=\"18\"></td><td><pre>    <span class=\"token keyword\">int</span> m_month<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"19\"></td><td><pre>    <span class=\"token keyword\">int</span> m_day<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"20\"></td><td><pre><span class=\"token punctuation\">&#125;</span><span class=\"token punctuation\">;</span></pre></td></tr></table></figure><p>初始化列表以一个<strong>冒号</strong>开始，接着是一个以<strong>逗号分隔的数据成员列表</strong>，每个<strong>成员变量</strong>后面跟一个放在<strong>括号中的初始值或表达式</strong>。</p>\n<p><mark>一个对象在实例化时，就是在初始化列表这里完成变量的定义与初始化的。如果没有初始化列表，也同样是在这里（正式进入构造函数前）完成定义。</mark></p>\n<p><strong>注意：</strong></p>\n<ol>\n<li>\n<p>每个成员变量在初始化列表中只能出现一次（只能初始化一次）。</p>\n</li>\n<li>\n<p>类中<mark>如果包含以下成员，必须放在初始化列表的位置进行初始化</mark>（因为定义在这里，而这些类型必须在定义时完成初始化）：</p>\n<ul>\n<li>引用成员变量</li>\n<li>const 成员变量</li>\n<li>自定义类型成员且该类没有默认构造函数</li>\n</ul>\n</li>\n<li>\n<p>为了统一，尽量使用初始化列表进行初始化。</p>\n</li>\n<li>\n<p>成员变量在类中的<mark>声明次序就是其在初始化列表中的初始化顺序</mark>，<strong>与其在初始化列表中的先后次序无关</strong>。</p>\n<p>比方说这样就是不行的，因为 m_1 声明在前，此时使用未完成定义的 m_2 来初始化是非法的：</p>\n<figure class=\"highlight cpp\"><figcaption data-lang=\"C++\"></figcaption><table><tr><td data-num=\"1\"></td><td><pre><span class=\"token keyword\">class</span> <span class=\"token class-name\">A</span></pre></td></tr><tr><td data-num=\"2\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"3\"></td><td><pre><span class=\"token keyword\">public</span><span class=\"token operator\">:</span></pre></td></tr><tr><td data-num=\"4\"></td><td><pre>    <span class=\"token function\">A</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">int</span> a<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"5\"></td><td><pre>    \t<span class=\"token operator\">:</span> <span class=\"token function\">m_2</span><span class=\"token punctuation\">(</span>a<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"6\"></td><td><pre>        <span class=\"token punctuation\">,</span> <span class=\"token function\">m_1</span><span class=\"token punctuation\">(</span>m_2<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"7\"></td><td><pre>    <span class=\"token punctuation\">&#123;</span><span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"8\"></td><td><pre>    </pre></td></tr><tr><td data-num=\"9\"></td><td><pre><span class=\"token keyword\">private</span><span class=\"token operator\">:</span></pre></td></tr><tr><td data-num=\"10\"></td><td><pre>    <span class=\"token keyword\">int</span> m_1<span class=\"token punctuation\">;</span>\t\t<span class=\"token comment\">// 声明</span></pre></td></tr><tr><td data-num=\"11\"></td><td><pre>    <span class=\"token keyword\">int</span> m_2<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"12\"></td><td><pre><span class=\"token punctuation\">&#125;</span><span class=\"token punctuation\">;</span></pre></td></tr></table></figure></li>\n</ol>\n<h3 id=\"隐式转换与explicit关键字\"><a class=\"anchor\" href=\"#隐式转换与explicit关键字\">#</a> 隐式转换与 explicit 关键字</h3>\n<h4 id=\"隐式转换\"><a class=\"anchor\" href=\"#隐式转换\">#</a> 隐式转换</h4>\n<p>对于<strong>接受单参构造函数</strong>，有这样一个额外的功能，就是<strong>隐式类型转换</strong>。</p>\n<p>接受单参构造函数有以下几种：</p>\n<ul>\n<li>构造函数只有一个参数。</li>\n<li>构造函数<strong>有多个参数，但只有第一个参数没有默认值</strong>。</li>\n<li>全缺省构造函数。</li>\n</ul>\n<p>以下面个类为例：</p>\n<figure class=\"highlight cpp\"><figcaption data-lang=\"C++\"></figcaption><table><tr><td data-num=\"1\"></td><td><pre><span class=\"token keyword\">class</span> <span class=\"token class-name\">Date</span></pre></td></tr><tr><td data-num=\"2\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"3\"></td><td><pre><span class=\"token keyword\">public</span><span class=\"token operator\">:</span></pre></td></tr><tr><td data-num=\"4\"></td><td><pre>    <span class=\"token function\">Date</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">int</span> year<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"5\"></td><td><pre>        <span class=\"token operator\">:</span> <span class=\"token function\">m_year</span><span class=\"token punctuation\">(</span>year<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"6\"></td><td><pre>        <span class=\"token punctuation\">,</span> <span class=\"token function\">m_month</span><span class=\"token punctuation\">(</span><span class=\"token number\">1</span><span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"7\"></td><td><pre>        <span class=\"token punctuation\">,</span> <span class=\"token function\">m_day</span><span class=\"token punctuation\">(</span><span class=\"token number\">1</span><span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"8\"></td><td><pre>    <span class=\"token punctuation\">&#123;</span><span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"9\"></td><td><pre>    </pre></td></tr><tr><td data-num=\"10\"></td><td><pre><span class=\"token keyword\">private</span><span class=\"token operator\">:</span></pre></td></tr><tr><td data-num=\"11\"></td><td><pre>    <span class=\"token keyword\">int</span> m_year<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"12\"></td><td><pre>    <span class=\"token keyword\">int</span> m_month<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"13\"></td><td><pre>    <span class=\"token keyword\">int</span> m_day<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"14\"></td><td><pre><span class=\"token punctuation\">&#125;</span><span class=\"token punctuation\">;</span></pre></td></tr></table></figure><p>我们可以写这样一段代码而符合语法：</p>\n<figure class=\"highlight cpp\"><figcaption data-lang=\"C++\"></figcaption><table><tr><td data-num=\"1\"></td><td><pre><span class=\"token keyword\">void</span> <span class=\"token function\">Test</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"2\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"3\"></td><td><pre>    Date <span class=\"token function\">d1</span><span class=\"token punctuation\">(</span><span class=\"token number\">2023</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"4\"></td><td><pre>    d1 <span class=\"token operator\">=</span> <span class=\"token number\">2024</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"5\"></td><td><pre><span class=\"token punctuation\">&#125;</span></pre></td></tr></table></figure><p>这里直接将 2024 赋值给 d1，就是一个隐式类型转换，将整型变为 Date 类类型。</p>\n<p><strong>过程其实分为三步：</strong></p>\n<ul>\n<li>编译器首先创建了一个<strong>临时的 Date 类对象</strong>。</li>\n<li>编译器调用单参构造函数使用 2024 初始化了这个临时对象。</li>\n<li>编译器再将这个临时对象调用<strong>赋值运算符重载</strong>（ <code>operator=</code> ）复制给 d1。</li>\n</ul>\n<p>（部分情况下编译器会优化这个过程导致步骤减少）</p>\n<h4 id=\"explicit关键字\"><a class=\"anchor\" href=\"#explicit关键字\">#</a> explicit 关键字</h4>\n<p>使用 explicit 关键字修饰的构造函数将被禁止隐式类型转换。</p>\n<p>比方说下面这段代码就会报错：</p>\n<figure class=\"highlight cpp\"><figcaption data-lang=\"C++\"></figcaption><table><tr><td data-num=\"1\"></td><td><pre><span class=\"token keyword\">class</span> <span class=\"token class-name\">Date</span></pre></td></tr><tr><td data-num=\"2\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"3\"></td><td><pre><span class=\"token keyword\">public</span><span class=\"token operator\">:</span></pre></td></tr><tr><td data-num=\"4\"></td><td><pre>    <span class=\"token keyword\">explicit</span> <span class=\"token function\">Date</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">int</span> year<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"5\"></td><td><pre>        <span class=\"token operator\">:</span> <span class=\"token function\">m_year</span><span class=\"token punctuation\">(</span>year<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"6\"></td><td><pre>        <span class=\"token punctuation\">,</span> <span class=\"token function\">m_month</span><span class=\"token punctuation\">(</span><span class=\"token number\">1</span><span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"7\"></td><td><pre>        <span class=\"token punctuation\">,</span> <span class=\"token function\">m_day</span><span class=\"token punctuation\">(</span><span class=\"token number\">1</span><span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"8\"></td><td><pre>    <span class=\"token punctuation\">&#123;</span><span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"9\"></td><td><pre>    </pre></td></tr><tr><td data-num=\"10\"></td><td><pre><span class=\"token keyword\">private</span><span class=\"token operator\">:</span></pre></td></tr><tr><td data-num=\"11\"></td><td><pre>    <span class=\"token keyword\">int</span> m_year<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"12\"></td><td><pre>    <span class=\"token keyword\">int</span> m_month<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"13\"></td><td><pre>    <span class=\"token keyword\">int</span> m_day<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"14\"></td><td><pre><span class=\"token punctuation\">&#125;</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"15\"></td><td><pre></pre></td></tr><tr><td data-num=\"16\"></td><td><pre><span class=\"token keyword\">void</span> <span class=\"token function\">Test</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"17\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"18\"></td><td><pre>    Date <span class=\"token function\">d1</span><span class=\"token punctuation\">(</span><span class=\"token number\">2023</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"19\"></td><td><pre>    d1 <span class=\"token operator\">=</span> <span class=\"token number\">2024</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"20\"></td><td><pre><span class=\"token punctuation\">&#125;</span></pre></td></tr></table></figure><h3 id=\"static成员\"><a class=\"anchor\" href=\"#static成员\">#</a> static 成员</h3>\n<p>声明为 static 的类成员称为类的<strong>静态成员</strong>，用 static 修饰的成员变量，称之为<strong>静态成员变量</strong>；用 static 修饰的<br />\n成员函数，称之为<strong>静态成员函数</strong>。</p>\n<p><mark>静态成员变量一定要在类外进行初始化。</mark></p>\n<p>比方说下面这个类具有统计已有对象数量的功能：</p>\n<figure class=\"highlight cpp\"><figcaption data-lang=\"C++\"></figcaption><table><tr><td data-num=\"1\"></td><td><pre><span class=\"token keyword\">class</span> <span class=\"token class-name\">A</span></pre></td></tr><tr><td data-num=\"2\"></td><td><pre><span class=\"token punctuation\">&#123;</span> </pre></td></tr><tr><td data-num=\"3\"></td><td><pre><span class=\"token keyword\">public</span><span class=\"token operator\">:</span></pre></td></tr><tr><td data-num=\"4\"></td><td><pre>    <span class=\"token function\">A</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">&#123;</span> <span class=\"token operator\">++</span>m_cnt<span class=\"token punctuation\">;</span> <span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"5\"></td><td><pre>    <span class=\"token function\">A</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">const</span> A<span class=\"token operator\">&amp;</span> t<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">&#123;</span> <span class=\"token operator\">++</span>m_cnt<span class=\"token punctuation\">;</span> <span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"6\"></td><td><pre>    <span class=\"token operator\">~</span><span class=\"token function\">A</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">&#123;</span> <span class=\"token operator\">--</span>m_cnt<span class=\"token punctuation\">;</span> <span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"7\"></td><td><pre>    <span class=\"token keyword\">static</span> <span class=\"token keyword\">int</span> <span class=\"token function\">GetCnt</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">&#123;</span> <span class=\"token keyword\">return</span> m_cnt<span class=\"token punctuation\">;</span> <span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"8\"></td><td><pre>    <span class=\"token keyword\">static</span> <span class=\"token keyword\">int</span> m_cnt<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"9\"></td><td><pre><span class=\"token punctuation\">&#125;</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"10\"></td><td><pre></pre></td></tr><tr><td data-num=\"11\"></td><td><pre><span class=\"token keyword\">int</span> A<span class=\"token double-colon punctuation\">::</span>m_cnt <span class=\"token operator\">=</span> <span class=\"token number\">0</span><span class=\"token punctuation\">;</span></pre></td></tr></table></figure><h4 id=\"static成员的特性\"><a class=\"anchor\" href=\"#static成员的特性\">#</a> static 成员的特性</h4>\n<ol>\n<li>静态成员为所有类对象所共享，不属于某个具体的对象，<strong>存放在静态区</strong>。</li>\n<li><strong>静态成员变量必须在类外定义</strong>，定义时不添加 static 关键字，<strong>类中只是声明</strong>。</li>\n<li>类静态成员可用 “<strong>类名：：静态成员</strong>” 或者 “<strong>对象。静态成员</strong>” 来访问。</li>\n<li><mark>静态成员函数没有隐藏的 this 指针</mark>，不能访问任何非静态成员（低权限）。</li>\n<li>静态成员也是类的成员，<strong>受 public、protected、private 访问限定符的限制</strong>。</li>\n</ol>\n<h3 id=\"友元\"><a class=\"anchor\" href=\"#友元\">#</a> 友元</h3>\n<p>友元是一种<strong>突破封装</strong>的方式，有时能为我们提供便利。但是友元会增加耦合度，破坏封装，<mark>不可滥用</mark>。</p>\n<h4 id=\"友元函数\"><a class=\"anchor\" href=\"#友元函数\">#</a> 友元函数</h4>\n<p>我们尝试重载函数时，没有去实现流输入操作符与流输出操作符的重载。因为 cout 的输出流对象和隐含的 this 指针在抢占第一个参数的位置，this 指针默认是第一个参数也就是左操作数，但是实际使用中 cout 需要是第一个形参对象才能正常使用。所以要将 operator&lt;&lt; 重载成全局函数。但这会导致类外没办法访问成员（直接将成员设置为公有是破坏封装的不可取的行为），此时就需要友元函数来解决这个问题。</p>\n<figure class=\"highlight cpp\"><figcaption data-lang=\"C++\"></figcaption><table><tr><td data-num=\"1\"></td><td><pre><span class=\"token macro property\"><span class=\"token directive-hash\">#</span><span class=\"token directive keyword\">include</span> <span class=\"token string\">&lt;iostream></span></span></pre></td></tr><tr><td data-num=\"2\"></td><td><pre></pre></td></tr><tr><td data-num=\"3\"></td><td><pre><span class=\"token keyword\">using</span> <span class=\"token keyword\">namespace</span> std<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"4\"></td><td><pre></pre></td></tr><tr><td data-num=\"5\"></td><td><pre><span class=\"token keyword\">class</span> <span class=\"token class-name\">Date</span></pre></td></tr><tr><td data-num=\"6\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"7\"></td><td><pre><span class=\"token keyword\">public</span><span class=\"token operator\">:</span></pre></td></tr><tr><td data-num=\"8\"></td><td><pre>\t<span class=\"token function\">Date</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">int</span> year<span class=\"token punctuation\">,</span> <span class=\"token keyword\">int</span> month<span class=\"token punctuation\">,</span> <span class=\"token keyword\">int</span> day<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"9\"></td><td><pre>\t<span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"10\"></td><td><pre>\t\tm_year <span class=\"token operator\">=</span> year<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"11\"></td><td><pre>\t\tm_month <span class=\"token operator\">=</span> month<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"12\"></td><td><pre>\t\tm_day <span class=\"token operator\">=</span> day<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"13\"></td><td><pre>\t<span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"14\"></td><td><pre></pre></td></tr><tr><td data-num=\"15\"></td><td><pre>\t<span class=\"token keyword\">friend</span> ostream<span class=\"token operator\">&amp;</span> <span class=\"token keyword\">operator</span><span class=\"token operator\">&lt;&lt;</span><span class=\"token punctuation\">(</span>ostream<span class=\"token operator\">&amp;</span> os<span class=\"token punctuation\">,</span> <span class=\"token keyword\">const</span> Date<span class=\"token operator\">&amp;</span> date<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"16\"></td><td><pre>\t<span class=\"token keyword\">friend</span> istream<span class=\"token operator\">&amp;</span> <span class=\"token keyword\">operator</span><span class=\"token operator\">>></span><span class=\"token punctuation\">(</span>istream<span class=\"token operator\">&amp;</span> is<span class=\"token punctuation\">,</span> Date<span class=\"token operator\">&amp;</span> date<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"17\"></td><td><pre></pre></td></tr><tr><td data-num=\"18\"></td><td><pre><span class=\"token keyword\">private</span><span class=\"token operator\">:</span></pre></td></tr><tr><td data-num=\"19\"></td><td><pre>\t<span class=\"token keyword\">int</span> m_year<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"20\"></td><td><pre>\t<span class=\"token keyword\">int</span> m_month<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"21\"></td><td><pre>\t<span class=\"token keyword\">int</span> m_day<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"22\"></td><td><pre><span class=\"token punctuation\">&#125;</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"23\"></td><td><pre></pre></td></tr><tr><td data-num=\"24\"></td><td><pre>ostream<span class=\"token operator\">&amp;</span> <span class=\"token keyword\">operator</span><span class=\"token operator\">&lt;&lt;</span><span class=\"token punctuation\">(</span>ostream<span class=\"token operator\">&amp;</span> os<span class=\"token punctuation\">,</span> <span class=\"token keyword\">const</span> Date<span class=\"token operator\">&amp;</span> date<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"25\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"26\"></td><td><pre>\tos <span class=\"token operator\">&lt;&lt;</span> date<span class=\"token punctuation\">.</span>m_year <span class=\"token operator\">&lt;&lt;</span> <span class=\"token string\">\"-\"</span> <span class=\"token operator\">&lt;&lt;</span> date<span class=\"token punctuation\">.</span>m_month <span class=\"token operator\">&lt;&lt;</span> <span class=\"token string\">\"-\"</span> <span class=\"token operator\">&lt;&lt;</span> date<span class=\"token punctuation\">.</span>m_day<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"27\"></td><td><pre>\t<span class=\"token keyword\">return</span> os<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"28\"></td><td><pre><span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"29\"></td><td><pre></pre></td></tr><tr><td data-num=\"30\"></td><td><pre>istream<span class=\"token operator\">&amp;</span> <span class=\"token keyword\">operator</span><span class=\"token operator\">>></span><span class=\"token punctuation\">(</span>istream<span class=\"token operator\">&amp;</span> is<span class=\"token punctuation\">,</span> Date<span class=\"token operator\">&amp;</span> date<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"31\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"32\"></td><td><pre>\tcout <span class=\"token operator\">&lt;&lt;</span> <span class=\"token string\">\"请输入年月日(使用空格分割)：>\"</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"33\"></td><td><pre>\tis <span class=\"token operator\">>></span> date<span class=\"token punctuation\">.</span>m_year <span class=\"token operator\">>></span> date<span class=\"token punctuation\">.</span>m_month <span class=\"token operator\">>></span> date<span class=\"token punctuation\">.</span>m_day<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"34\"></td><td><pre>\t<span class=\"token keyword\">return</span> is<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"35\"></td><td><pre><span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"36\"></td><td><pre></pre></td></tr><tr><td data-num=\"37\"></td><td><pre><span class=\"token keyword\">int</span> <span class=\"token function\">main</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"38\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"39\"></td><td><pre>\tDate <span class=\"token function\">date1</span><span class=\"token punctuation\">(</span><span class=\"token number\">2024</span><span class=\"token punctuation\">,</span> <span class=\"token number\">5</span><span class=\"token punctuation\">,</span> <span class=\"token number\">25</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"40\"></td><td><pre>\tDate <span class=\"token function\">date2</span><span class=\"token punctuation\">(</span><span class=\"token number\">2024</span><span class=\"token punctuation\">,</span> <span class=\"token number\">5</span><span class=\"token punctuation\">,</span> <span class=\"token number\">26</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"41\"></td><td><pre>\tcout <span class=\"token operator\">&lt;&lt;</span> date1 <span class=\"token operator\">&lt;&lt;</span> endl <span class=\"token operator\">&lt;&lt;</span> date2 <span class=\"token operator\">&lt;&lt;</span> endl<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"42\"></td><td><pre></pre></td></tr><tr><td data-num=\"43\"></td><td><pre>\tcin <span class=\"token operator\">>></span> date1<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"44\"></td><td><pre>\tcout <span class=\"token operator\">&lt;&lt;</span> date1 <span class=\"token operator\">&lt;&lt;</span> endl<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"45\"></td><td><pre></pre></td></tr><tr><td data-num=\"46\"></td><td><pre>\t<span class=\"token keyword\">return</span> <span class=\"token number\">0</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"47\"></td><td><pre><span class=\"token punctuation\">&#125;</span></pre></td></tr></table></figure><p><mark>友元函数可以直接访问类的私有成员，它是定义在类外部的普通函数，不属于任何类，但需要在类的内部声明，声明时需要加 friend 关键字。</mark></p>\n<ol>\n<li>友元函数可访问类的私有和保护成员，但<strong>不是类的成员函数</strong>。</li>\n<li>友元函数<strong>不能用 const 修饰</strong>。</li>\n<li>友元函数可以在类定义的任何地方声明，<strong>不受类访问限定符限制。</strong></li>\n<li>一<strong>个函数可以是多个类的友元函数</strong>。</li>\n<li>友元函数的调用与普通函数的调用原理相同。</li>\n</ol>\n<h4 id=\"友元类\"><a class=\"anchor\" href=\"#友元类\">#</a> 友元类</h4>\n<ul>\n<li>友元类的所有成员函数都可以是另一个类的友元函数，都可以访问另一个类中的非公有成员。</li>\n<li>友元关系是<strong>单向的</strong>，不具有交换性。</li>\n<li><strong>友元关系不能传递</strong>。如果 B 是 A 的友元，C 是 B 的友元，那么不能说明 C 是 A 的友元，不能访问 A 的非公有成员。</li>\n<li>友元关系<strong>不能继承</strong>。这个先记住就行，后面继承的时候再说。</li>\n</ul>\n<figure class=\"highlight cpp\"><figcaption data-lang=\"C++\"></figcaption><table><tr><td data-num=\"1\"></td><td><pre><span class=\"token macro property\"><span class=\"token directive-hash\">#</span><span class=\"token directive keyword\">include</span> <span class=\"token string\">&lt;iostream></span></span></pre></td></tr><tr><td data-num=\"2\"></td><td><pre></pre></td></tr><tr><td data-num=\"3\"></td><td><pre><span class=\"token keyword\">using</span> <span class=\"token keyword\">namespace</span> std<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"4\"></td><td><pre></pre></td></tr><tr><td data-num=\"5\"></td><td><pre><span class=\"token keyword\">class</span> <span class=\"token class-name\">Date</span></pre></td></tr><tr><td data-num=\"6\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"7\"></td><td><pre>\t<span class=\"token keyword\">friend</span> <span class=\"token keyword\">class</span> <span class=\"token class-name\">Time</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"8\"></td><td><pre></pre></td></tr><tr><td data-num=\"9\"></td><td><pre><span class=\"token keyword\">public</span><span class=\"token operator\">:</span> </pre></td></tr><tr><td data-num=\"10\"></td><td><pre>\t<span class=\"token function\">Date</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">int</span> y<span class=\"token punctuation\">,</span> <span class=\"token keyword\">int</span> m<span class=\"token punctuation\">,</span> <span class=\"token keyword\">int</span> d<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"11\"></td><td><pre>\t\t<span class=\"token operator\">:</span> <span class=\"token function\">m_year</span><span class=\"token punctuation\">(</span>y<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"12\"></td><td><pre>\t\t<span class=\"token punctuation\">,</span> <span class=\"token function\">m_month</span><span class=\"token punctuation\">(</span>m<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"13\"></td><td><pre>\t\t<span class=\"token punctuation\">,</span> <span class=\"token function\">m_day</span><span class=\"token punctuation\">(</span>d<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"14\"></td><td><pre>\t<span class=\"token punctuation\">&#123;</span><span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"15\"></td><td><pre></pre></td></tr><tr><td data-num=\"16\"></td><td><pre>\t<span class=\"token keyword\">void</span> <span class=\"token function\">show</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"17\"></td><td><pre>\t<span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"18\"></td><td><pre>\t\tcout <span class=\"token operator\">&lt;&lt;</span> m_year <span class=\"token operator\">&lt;&lt;</span> <span class=\"token string\">\"-\"</span> <span class=\"token operator\">&lt;&lt;</span> m_month <span class=\"token operator\">&lt;&lt;</span> <span class=\"token string\">\"-\"</span> <span class=\"token operator\">&lt;&lt;</span> m_day <span class=\"token operator\">&lt;&lt;</span> endl<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"19\"></td><td><pre>\t<span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"20\"></td><td><pre></pre></td></tr><tr><td data-num=\"21\"></td><td><pre><span class=\"token keyword\">private</span><span class=\"token operator\">:</span></pre></td></tr><tr><td data-num=\"22\"></td><td><pre>\t<span class=\"token keyword\">int</span> m_year<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"23\"></td><td><pre>\t<span class=\"token keyword\">int</span> m_month<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"24\"></td><td><pre>\t<span class=\"token keyword\">int</span> m_day<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"25\"></td><td><pre><span class=\"token punctuation\">&#125;</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"26\"></td><td><pre></pre></td></tr><tr><td data-num=\"27\"></td><td><pre><span class=\"token keyword\">class</span> <span class=\"token class-name\">Time</span></pre></td></tr><tr><td data-num=\"28\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"29\"></td><td><pre><span class=\"token keyword\">public</span><span class=\"token operator\">:</span></pre></td></tr><tr><td data-num=\"30\"></td><td><pre>\t<span class=\"token function\">Time</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">int</span> h<span class=\"token punctuation\">,</span> <span class=\"token keyword\">int</span> m<span class=\"token punctuation\">,</span> <span class=\"token keyword\">int</span> s<span class=\"token punctuation\">,</span> <span class=\"token keyword\">int</span> y<span class=\"token punctuation\">,</span> <span class=\"token keyword\">int</span> month<span class=\"token punctuation\">,</span> <span class=\"token keyword\">int</span> d<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"31\"></td><td><pre>\t\t<span class=\"token operator\">:</span> <span class=\"token function\">m_hour</span><span class=\"token punctuation\">(</span>h<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"32\"></td><td><pre>\t\t<span class=\"token punctuation\">,</span> <span class=\"token function\">m_minute</span><span class=\"token punctuation\">(</span>m<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"33\"></td><td><pre>\t\t<span class=\"token punctuation\">,</span> <span class=\"token function\">m_second</span><span class=\"token punctuation\">(</span>s<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"34\"></td><td><pre>\t\t<span class=\"token punctuation\">,</span> <span class=\"token function\">m_date</span><span class=\"token punctuation\">(</span>y<span class=\"token punctuation\">,</span> month<span class=\"token punctuation\">,</span> d<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"35\"></td><td><pre>\t<span class=\"token punctuation\">&#123;</span><span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"36\"></td><td><pre></pre></td></tr><tr><td data-num=\"37\"></td><td><pre>\t<span class=\"token keyword\">void</span> <span class=\"token function\">show</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"38\"></td><td><pre>\t<span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"39\"></td><td><pre>\t\tcout <span class=\"token operator\">&lt;&lt;</span> m_hour <span class=\"token operator\">&lt;&lt;</span> <span class=\"token string\">\":\"</span> <span class=\"token operator\">&lt;&lt;</span> m_minute <span class=\"token operator\">&lt;&lt;</span> <span class=\"token string\">\":\"</span> <span class=\"token operator\">&lt;&lt;</span> m_second <span class=\"token operator\">&lt;&lt;</span> endl<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"40\"></td><td><pre>\t\tm_date<span class=\"token punctuation\">.</span><span class=\"token function\">show</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"41\"></td><td><pre>\t<span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"42\"></td><td><pre></pre></td></tr><tr><td data-num=\"43\"></td><td><pre><span class=\"token keyword\">private</span><span class=\"token operator\">:</span></pre></td></tr><tr><td data-num=\"44\"></td><td><pre>\t<span class=\"token keyword\">int</span> m_hour<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"45\"></td><td><pre>\t<span class=\"token keyword\">int</span> m_minute<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"46\"></td><td><pre>\t<span class=\"token keyword\">int</span> m_second<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"47\"></td><td><pre>\tDate m_date<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"48\"></td><td><pre><span class=\"token punctuation\">&#125;</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"49\"></td><td><pre></pre></td></tr><tr><td data-num=\"50\"></td><td><pre><span class=\"token keyword\">int</span> <span class=\"token function\">main</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"51\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"52\"></td><td><pre>\tTime <span class=\"token function\">t</span><span class=\"token punctuation\">(</span><span class=\"token number\">12</span><span class=\"token punctuation\">,</span> <span class=\"token number\">23</span><span class=\"token punctuation\">,</span> <span class=\"token number\">34</span><span class=\"token punctuation\">,</span> <span class=\"token number\">2020</span><span class=\"token punctuation\">,</span> <span class=\"token number\">5</span><span class=\"token punctuation\">,</span> <span class=\"token number\">30</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"53\"></td><td><pre>\tt<span class=\"token punctuation\">.</span><span class=\"token function\">show</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"54\"></td><td><pre></pre></td></tr><tr><td data-num=\"55\"></td><td><pre>\t<span class=\"token keyword\">return</span> <span class=\"token number\">0</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"56\"></td><td><pre><span class=\"token punctuation\">&#125;</span></pre></td></tr></table></figure><h3 id=\"内部类\"><a class=\"anchor\" href=\"#内部类\">#</a> 内部类</h3>\n<p>如果<strong>一个类定义在另外一个类的内部</strong>，那这个类就是内部类。</p>\n<p>但是，假设类 B 定义在类 A 的内部，类 B 和类 A 依旧是独立的，<mark>并不是说外部类就能直接访问内部类</mark>。反而是内部类可以直接访问外部类中的静态成员。</p>\n<p>在有外部类的对象参数的情况下，内部类可以借此访问外部类中的所有成员。</p>\n<p>或者说，<mark>内部类可以认为就是一种特殊的外部类的友元类</mark>。</p>\n<figure class=\"highlight cpp\"><figcaption data-lang=\"C++\"></figcaption><table><tr><td data-num=\"1\"></td><td><pre><span class=\"token macro property\"><span class=\"token directive-hash\">#</span><span class=\"token directive keyword\">include</span> <span class=\"token string\">&lt;iostream></span></span></pre></td></tr><tr><td data-num=\"2\"></td><td><pre></pre></td></tr><tr><td data-num=\"3\"></td><td><pre><span class=\"token keyword\">using</span> <span class=\"token keyword\">namespace</span> std<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"4\"></td><td><pre></pre></td></tr><tr><td data-num=\"5\"></td><td><pre><span class=\"token keyword\">class</span> <span class=\"token class-name\">A</span></pre></td></tr><tr><td data-num=\"6\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"7\"></td><td><pre><span class=\"token keyword\">public</span><span class=\"token operator\">:</span></pre></td></tr><tr><td data-num=\"8\"></td><td><pre>\t<span class=\"token keyword\">class</span> <span class=\"token class-name\">B</span></pre></td></tr><tr><td data-num=\"9\"></td><td><pre>\t<span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"10\"></td><td><pre>\t<span class=\"token keyword\">public</span><span class=\"token operator\">:</span></pre></td></tr><tr><td data-num=\"11\"></td><td><pre>\t\t<span class=\"token keyword\">void</span> <span class=\"token function\">show</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">const</span> A<span class=\"token operator\">&amp;</span> AA<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"12\"></td><td><pre>\t\t<span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"13\"></td><td><pre>\t\t\tcout <span class=\"token operator\">&lt;&lt;</span> a <span class=\"token operator\">&lt;&lt;</span> endl<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"14\"></td><td><pre>\t\t\tcout <span class=\"token operator\">&lt;&lt;</span> AA<span class=\"token punctuation\">.</span>b <span class=\"token operator\">&lt;&lt;</span> endl<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"15\"></td><td><pre>\t\t<span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"16\"></td><td><pre>\t<span class=\"token punctuation\">&#125;</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"17\"></td><td><pre></pre></td></tr><tr><td data-num=\"18\"></td><td><pre><span class=\"token keyword\">private</span><span class=\"token operator\">:</span></pre></td></tr><tr><td data-num=\"19\"></td><td><pre>\t<span class=\"token keyword\">static</span> <span class=\"token keyword\">int</span> a<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"20\"></td><td><pre>\t<span class=\"token keyword\">int</span> b<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"21\"></td><td><pre><span class=\"token punctuation\">&#125;</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"22\"></td><td><pre></pre></td></tr><tr><td data-num=\"23\"></td><td><pre><span class=\"token keyword\">int</span> A<span class=\"token double-colon punctuation\">::</span>a <span class=\"token operator\">=</span> <span class=\"token number\">10</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"24\"></td><td><pre></pre></td></tr><tr><td data-num=\"25\"></td><td><pre><span class=\"token keyword\">int</span> <span class=\"token function\">main</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"26\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"27\"></td><td><pre>\tA<span class=\"token double-colon punctuation\">::</span>B BB<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"28\"></td><td><pre>\tBB<span class=\"token punctuation\">.</span><span class=\"token function\">show</span><span class=\"token punctuation\">(</span><span class=\"token function\">A</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"29\"></td><td><pre></pre></td></tr><tr><td data-num=\"30\"></td><td><pre>\t<span class=\"token keyword\">return</span> <span class=\"token number\">0</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"31\"></td><td><pre><span class=\"token punctuation\">&#125;</span></pre></td></tr></table></figure><p>注意：</p>\n<ul>\n<li>内部类定义在类的 public、protected、private 都是可以的。</li>\n<li>内部类可以直接访问外部类的 static 成员，不需要类名。</li>\n<li>如果<mark>用 sizeof 去取外部类的大小，不用考虑内部类，直接当做没有内部类即可</mark>，与结构体嵌套有很大区别。</li>\n</ul>\n<p>但是即使我们说内部类可以理解为外部类的友元类，我们可以把上面的时间类写成这样吗：</p>\n<figure class=\"highlight cpp\"><figcaption data-lang=\"C++\"></figcaption><table><tr><td data-num=\"1\"></td><td><pre><span class=\"token macro property\"><span class=\"token directive-hash\">#</span><span class=\"token directive keyword\">include</span> <span class=\"token string\">&lt;iostream></span></span></pre></td></tr><tr><td data-num=\"2\"></td><td><pre></pre></td></tr><tr><td data-num=\"3\"></td><td><pre><span class=\"token keyword\">using</span> <span class=\"token keyword\">namespace</span> std<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"4\"></td><td><pre></pre></td></tr><tr><td data-num=\"5\"></td><td><pre><span class=\"token keyword\">class</span> <span class=\"token class-name\">Date</span></pre></td></tr><tr><td data-num=\"6\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"7\"></td><td><pre><span class=\"token keyword\">public</span><span class=\"token operator\">:</span></pre></td></tr><tr><td data-num=\"8\"></td><td><pre>\t<span class=\"token function\">Date</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">int</span> y<span class=\"token punctuation\">,</span> <span class=\"token keyword\">int</span> m<span class=\"token punctuation\">,</span> <span class=\"token keyword\">int</span> d<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"9\"></td><td><pre>\t\t<span class=\"token operator\">:</span> <span class=\"token function\">m_year</span><span class=\"token punctuation\">(</span>y<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"10\"></td><td><pre>\t\t<span class=\"token punctuation\">,</span> <span class=\"token function\">m_month</span><span class=\"token punctuation\">(</span>m<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"11\"></td><td><pre>\t\t<span class=\"token punctuation\">,</span> <span class=\"token function\">m_day</span><span class=\"token punctuation\">(</span>d<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"12\"></td><td><pre>\t<span class=\"token punctuation\">&#123;</span><span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"13\"></td><td><pre></pre></td></tr><tr><td data-num=\"14\"></td><td><pre>\t<span class=\"token keyword\">void</span> <span class=\"token function\">show</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"15\"></td><td><pre>\t<span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"16\"></td><td><pre>\t\tcout <span class=\"token operator\">&lt;&lt;</span> m_year <span class=\"token operator\">&lt;&lt;</span> <span class=\"token string\">\"-\"</span> <span class=\"token operator\">&lt;&lt;</span> m_month <span class=\"token operator\">&lt;&lt;</span> <span class=\"token string\">\"-\"</span> <span class=\"token operator\">&lt;&lt;</span> m_day <span class=\"token operator\">&lt;&lt;</span> endl<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"17\"></td><td><pre>\t<span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"18\"></td><td><pre></pre></td></tr><tr><td data-num=\"19\"></td><td><pre><span class=\"token keyword\">private</span><span class=\"token operator\">:</span></pre></td></tr><tr><td data-num=\"20\"></td><td><pre>\t<span class=\"token keyword\">int</span> m_year<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"21\"></td><td><pre>\t<span class=\"token keyword\">int</span> m_month<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"22\"></td><td><pre>\t<span class=\"token keyword\">int</span> m_day<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"23\"></td><td><pre></pre></td></tr><tr><td data-num=\"24\"></td><td><pre>\t<span class=\"token keyword\">class</span> <span class=\"token class-name\">Time</span></pre></td></tr><tr><td data-num=\"25\"></td><td><pre>\t<span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"26\"></td><td><pre>\t<span class=\"token keyword\">public</span><span class=\"token operator\">:</span></pre></td></tr><tr><td data-num=\"27\"></td><td><pre>\t\t<span class=\"token function\">Time</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">int</span> hh<span class=\"token punctuation\">,</span> <span class=\"token keyword\">int</span> mm<span class=\"token punctuation\">,</span> <span class=\"token keyword\">int</span> ss<span class=\"token punctuation\">,</span> <span class=\"token keyword\">int</span> y<span class=\"token punctuation\">,</span> <span class=\"token keyword\">int</span> m<span class=\"token punctuation\">,</span> <span class=\"token keyword\">int</span> d<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"28\"></td><td><pre>\t\t\t<span class=\"token operator\">:</span> <span class=\"token function\">m_hour</span><span class=\"token punctuation\">(</span>hh<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"29\"></td><td><pre>\t\t\t<span class=\"token punctuation\">,</span> <span class=\"token function\">m_minute</span><span class=\"token punctuation\">(</span>mm<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"30\"></td><td><pre>\t\t\t<span class=\"token punctuation\">,</span> <span class=\"token function\">m_second</span><span class=\"token punctuation\">(</span>ss<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"31\"></td><td><pre>\t\t\t<span class=\"token punctuation\">,</span> <span class=\"token function\">m_date</span><span class=\"token punctuation\">(</span>y<span class=\"token punctuation\">,</span> m<span class=\"token punctuation\">,</span> d<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"32\"></td><td><pre>\t\t<span class=\"token punctuation\">&#123;</span><span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"33\"></td><td><pre></pre></td></tr><tr><td data-num=\"34\"></td><td><pre>\t\t<span class=\"token keyword\">void</span> <span class=\"token function\">show</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">const</span> Date<span class=\"token operator\">&amp;</span> dd<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"35\"></td><td><pre>\t\t<span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"36\"></td><td><pre>\t\t\tcout <span class=\"token operator\">&lt;&lt;</span> m_hour <span class=\"token operator\">&lt;&lt;</span> <span class=\"token string\">\":\"</span> <span class=\"token operator\">&lt;&lt;</span> m_minute <span class=\"token operator\">&lt;&lt;</span> <span class=\"token string\">\":\"</span> <span class=\"token operator\">&lt;&lt;</span> m_second <span class=\"token operator\">&lt;&lt;</span> endl<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"37\"></td><td><pre>\t\t\tcout <span class=\"token operator\">&lt;&lt;</span> dd<span class=\"token punctuation\">.</span>m_year <span class=\"token operator\">&lt;&lt;</span> <span class=\"token string\">\"-\"</span> <span class=\"token operator\">&lt;&lt;</span> dd<span class=\"token punctuation\">.</span>m_month <span class=\"token operator\">&lt;&lt;</span> <span class=\"token string\">\"-\"</span> <span class=\"token operator\">&lt;&lt;</span> dd<span class=\"token punctuation\">.</span>m_day <span class=\"token operator\">&lt;&lt;</span> endl<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"38\"></td><td><pre>\t\t<span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"39\"></td><td><pre></pre></td></tr><tr><td data-num=\"40\"></td><td><pre>\t<span class=\"token keyword\">private</span><span class=\"token operator\">:</span></pre></td></tr><tr><td data-num=\"41\"></td><td><pre>\t\t<span class=\"token keyword\">int</span> m_hour<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"42\"></td><td><pre>\t\t<span class=\"token keyword\">int</span> m_minute<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"43\"></td><td><pre>\t\t<span class=\"token keyword\">int</span> m_second<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"44\"></td><td><pre>\t<span class=\"token punctuation\">&#125;</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"45\"></td><td><pre><span class=\"token punctuation\">&#125;</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"46\"></td><td><pre></pre></td></tr><tr><td data-num=\"47\"></td><td><pre><span class=\"token keyword\">int</span> <span class=\"token function\">main</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"48\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"49\"></td><td><pre>\tDate<span class=\"token double-colon punctuation\">::</span>Time <span class=\"token function\">t</span><span class=\"token punctuation\">(</span><span class=\"token number\">10</span><span class=\"token punctuation\">,</span> <span class=\"token number\">20</span><span class=\"token punctuation\">,</span> <span class=\"token number\">30</span><span class=\"token punctuation\">,</span> <span class=\"token number\">2020</span><span class=\"token punctuation\">,</span> <span class=\"token number\">5</span><span class=\"token punctuation\">,</span> <span class=\"token number\">30</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"50\"></td><td><pre></pre></td></tr><tr><td data-num=\"51\"></td><td><pre>\t<span class=\"token keyword\">return</span> <span class=\"token number\">0</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"52\"></td><td><pre><span class=\"token punctuation\">&#125;</span></pre></td></tr></table></figure><p>答案是<mark>否定</mark>的，此时报错：不允许使用不完整的类型。</p>\n<p>在 C++ 中，<strong>一个类在其自身完整定义之前不能实例化其自身的对象</strong>。 <code>Date</code>  类试图在其内部类  <code>Time</code>  中实例化  <code>Date</code>  类型的  <code>m_date</code>  成员，这导致了编译错误。</p>\n<h3 id=\"匿名对象\"><a class=\"anchor\" href=\"#匿名对象\">#</a> 匿名对象</h3>\n<p>就像匿名结构体一样，类也有匿名对象。</p>\n<p>匿名对象是指在创建时不赋予显式名称的对象。匿名对象通常用于<strong>一次性使用</strong>的场景，尤其是在不需要在其他地方引用该对象的情况下。匿名对象的<strong>生命周期只在当前行</strong>。</p>\n<figure class=\"highlight cpp\"><figcaption data-lang=\"C++\"></figcaption><table><tr><td data-num=\"1\"></td><td><pre><span class=\"token macro property\"><span class=\"token directive-hash\">#</span><span class=\"token directive keyword\">include</span> <span class=\"token string\">&lt;iostream></span></span></pre></td></tr><tr><td data-num=\"2\"></td><td><pre></pre></td></tr><tr><td data-num=\"3\"></td><td><pre><span class=\"token keyword\">using</span> <span class=\"token keyword\">namespace</span> std<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"4\"></td><td><pre></pre></td></tr><tr><td data-num=\"5\"></td><td><pre><span class=\"token keyword\">class</span> <span class=\"token class-name\">A</span></pre></td></tr><tr><td data-num=\"6\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"7\"></td><td><pre><span class=\"token keyword\">public</span><span class=\"token operator\">:</span></pre></td></tr><tr><td data-num=\"8\"></td><td><pre>    <span class=\"token function\">A</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">int</span> k<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"9\"></td><td><pre>        <span class=\"token operator\">:</span> <span class=\"token function\">m_m</span><span class=\"token punctuation\">(</span>k<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"10\"></td><td><pre>    <span class=\"token punctuation\">&#123;</span><span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"11\"></td><td><pre>    </pre></td></tr><tr><td data-num=\"12\"></td><td><pre>    <span class=\"token operator\">~</span><span class=\"token function\">A</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">&#123;</span><span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"13\"></td><td><pre>    </pre></td></tr><tr><td data-num=\"14\"></td><td><pre>    <span class=\"token keyword\">int</span> <span class=\"token function\">GetSquare</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"15\"></td><td><pre>    <span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"16\"></td><td><pre>        <span class=\"token keyword\">return</span> m_m <span class=\"token operator\">*</span> m_m<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"17\"></td><td><pre>    <span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"18\"></td><td><pre>    </pre></td></tr><tr><td data-num=\"19\"></td><td><pre><span class=\"token keyword\">private</span><span class=\"token operator\">:</span></pre></td></tr><tr><td data-num=\"20\"></td><td><pre>    <span class=\"token keyword\">int</span> m_m<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"21\"></td><td><pre><span class=\"token punctuation\">&#125;</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"22\"></td><td><pre></pre></td></tr><tr><td data-num=\"23\"></td><td><pre><span class=\"token keyword\">void</span> <span class=\"token function\">test</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"24\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"25\"></td><td><pre>    <span class=\"token comment\">// 有名对象计算平方</span></pre></td></tr><tr><td data-num=\"26\"></td><td><pre>    A <span class=\"token function\">a</span><span class=\"token punctuation\">(</span><span class=\"token number\">2</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\t</pre></td></tr><tr><td data-num=\"27\"></td><td><pre>    cout <span class=\"token operator\">&lt;&lt;</span> a<span class=\"token punctuation\">.</span><span class=\"token function\">GetSquare</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">&lt;&lt;</span> endl<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"28\"></td><td><pre>    </pre></td></tr><tr><td data-num=\"29\"></td><td><pre>    <span class=\"token comment\">// 匿名对象计算平方</span></pre></td></tr><tr><td data-num=\"30\"></td><td><pre>    cout <span class=\"token operator\">&lt;&lt;</span> <span class=\"token function\">A</span><span class=\"token punctuation\">(</span><span class=\"token number\">2</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span><span class=\"token function\">GetSquare</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">&lt;&lt;</span> endl<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"31\"></td><td><pre><span class=\"token punctuation\">&#125;</span></pre></td></tr></table></figure>",
            "tags": [
                "计算机科学",
                "C++笔记",
                "C++",
                "类"
            ]
        },
        {
            "id": "https://www.starlinglin.top/computer-science/misc/%E5%9C%A8CentOS7%E4%B8%8B%E6%9E%84%E5%BB%BATeamSpeak%E6%9C%8D%E5%8A%A1%E5%99%A8%E5%B9%B6%E5%A2%9E%E5%8A%A0%E7%BD%91%E6%98%93%E4%BA%91%E7%82%B9%E6%AD%8C%E6%8F%92%E4%BB%B6/",
            "url": "https://www.starlinglin.top/computer-science/misc/%E5%9C%A8CentOS7%E4%B8%8B%E6%9E%84%E5%BB%BATeamSpeak%E6%9C%8D%E5%8A%A1%E5%99%A8%E5%B9%B6%E5%A2%9E%E5%8A%A0%E7%BD%91%E6%98%93%E4%BA%91%E7%82%B9%E6%AD%8C%E6%8F%92%E4%BB%B6/",
            "title": "在CentOS7下构建TeamSpeak服务器并增加网易云点歌插件",
            "date_published": "2024-05-29T20:06:09.000Z",
            "content_html": "<div class=\"note info\">\n<p>本人服务器配置为 CentOS 7.9 64 位。</p>\n</div>\n<div class=\"note warning\">\n<p>部分内容有时效性，不能保证可以复现。</p>\n</div>\n<p>首先 ssh 登录到我们的服务器。</p>\n<h2 id=\"部署teamspeak\"><a class=\"anchor\" href=\"#部署teamspeak\">#</a> 部署 TeamSpeak</h2>\n<h3 id=\"创建一个新用户\"><a class=\"anchor\" href=\"#创建一个新用户\">#</a> 创建一个新用户</h3>\n<p>这是为了方便管理，而且部分操作不方便通过 root 账号完成。</p>\n<p>这里我们创建一个名为 teamspeak 的账户：</p>\n<figure class=\"highlight bash\"><figcaption data-lang=\"bash\"><span>XShell</span></figcaption><table><tr><td data-num=\"1\"></td><td data-command=\"\"></td><td><pre><span class=\"token comment\"># 新建用户 teamspeak</span></pre></td></tr><tr><td data-num=\"2\"></td><td data-command=\"[root@Starling] $\"></td><td><pre><span class=\"token function\">useradd</span> teamspeak</pre></td></tr><tr><td data-num=\"3\"></td><td data-command=\"\"></td><td><pre><span class=\"token comment\"># 给予 sudo 权限</span></pre></td></tr><tr><td data-num=\"4\"></td><td data-command=\"[root@Starling] $\"></td><td><pre><span class=\"token function\">usermod</span> <span class=\"token parameter variable\">-a</span> <span class=\"token parameter variable\">-G</span> <span class=\"token function\">sudo</span> teamspeak</pre></td></tr><tr><td data-num=\"5\"></td><td data-command=\"\"></td><td><pre><span class=\"token comment\"># 设置密码</span></pre></td></tr><tr><td data-num=\"6\"></td><td data-command=\"[root@Starling] $\"></td><td><pre><span class=\"token function\">passwd</span> teamspeak</pre></td></tr><tr><td data-num=\"7\"></td><td data-command=\"\"></td><td><pre><span class=\"token comment\"># 切换用户并定位到家目录</span></pre></td></tr><tr><td data-num=\"8\"></td><td data-command=\"[root@Starling] $\"></td><td><pre><span class=\"token function\">su</span> teamspeak</pre></td></tr><tr><td data-num=\"9\"></td><td data-command=\"[teamspeak@Starling] $\"></td><td><pre><span class=\"token builtin class-name\">cd</span> ~</pre></td></tr></table></figure><h3 id=\"下载并解压服务端\"><a class=\"anchor\" href=\"#下载并解压服务端\">#</a> 下载并解压服务端</h3>\n<h4 id=\"下载\"><a class=\"anchor\" href=\"#下载\">#</a> 下载</h4>\n<p><div class=\"links\"><div class=\"item\" title=\"Teamspeak服务端下载\"><span class=\"exturl image\" data-url=\"aHR0cHM6Ly93d3cudGVhbXNwZWFrLmNvbS96aC1DTi9kb3dubG9hZHMvI3NlcnZlcg==\" data-background-image=\"/images/404.png\"></span>\n          <div class=\"info\">\n          <span class=\"exturl title\" data-url=\"aHR0cHM6Ly93d3cudGVhbXNwZWFrLmNvbS96aC1DTi9kb3dubG9hZHMvI3NlcnZlcg==\">Teamspeak服务端下载</span>\n          <p class=\"desc\">https://www.teamspeak.com/zh-CN/downloads/#server</p>\n          </div></div></div></p>\n<p>以上为官网下载地址，可以在那里查看最新版本，可以选择从官网下载下来再传输到服务器上，也可以直接命令行下载：</p>\n<figure class=\"highlight bash\"><figcaption data-lang=\"bash\"><span>XShell</span></figcaption><table><tr><td data-num=\"1\"></td><td data-command=\"\"></td><td><pre><span class=\"token comment\"># 需要服务器已安装 wget</span></pre></td></tr><tr><td data-num=\"2\"></td><td data-command=\"[teamspeak@Starling] $\"></td><td><pre><span class=\"token function\">wget</span> https://files.teamspeak-services.com/releases/server/3.13.7/teamspeak3-server_linux_amd64-3.13.7.tar.bz2</pre></td></tr></table></figure><details class=\"primary\"><summary>如果你的服务器没有安装wget</summary><div>\n<p>注意使用 root 账号。</p>\n<figure class=\"highlight bash\"><figcaption data-lang=\"bash\"><span>XShell</span></figcaption><table><tr><td data-num=\"1\"></td><td data-command=\"\"></td><td><pre><span class=\"token comment\"># 使用 yum 安装 wget</span></pre></td></tr><tr><td data-num=\"2\"></td><td data-command=\"[root@Starling] $\"></td><td><pre><span class=\"token function\">sudo</span> yum <span class=\"token function\">install</span> <span class=\"token parameter variable\">-y</span> <span class=\"token function\">wget</span></pre></td></tr></table></figure></div></details>\n<h4 id=\"解压\"><a class=\"anchor\" href=\"#解压\">#</a> 解压</h4>\n<figure class=\"highlight bash\"><figcaption data-lang=\"bash\"><span>XShell</span></figcaption><table><tr><td data-num=\"1\"></td><td data-command=\"\"></td><td><pre><span class=\"token comment\"># 使用 tar 命令解压</span></pre></td></tr><tr><td data-num=\"2\"></td><td data-command=\"[teamspeak@Starling] $\"></td><td><pre><span class=\"token function\">tar</span> <span class=\"token parameter variable\">-xvf</span> teamspeak3-server_linux_amd64-3.13.7.tar.bz2</pre></td></tr></table></figure><details class=\"primary\"><summary>如果解压报错Error is not recoverable: exiting now</summary><div>\n<p>需要安装 bz2 相关内容，使用 root 账号：</p>\n<figure class=\"highlight bash\"><figcaption data-lang=\"bash\"><span>XShell</span></figcaption><table><tr><td data-num=\"1\"></td><td data-command=\"\"></td><td><pre><span class=\"token comment\"># 使用 yum 安装 bzip2</span></pre></td></tr><tr><td data-num=\"2\"></td><td data-command=\"[root@Starling] $\"></td><td><pre><span class=\"token function\">sudo</span> yum <span class=\"token function\">install</span> <span class=\"token parameter variable\">-y</span> <span class=\"token function\">bzip2</span></pre></td></tr></table></figure></div></details>\n<p>创建 teamspeak 目录，把解压后的东西塞进去：</p>\n<figure class=\"highlight bash\"><figcaption data-lang=\"bash\"><span>XShell</span></figcaption><table><tr><td data-num=\"1\"></td><td data-command=\"[teamspeak@Starling] $\"></td><td><pre><span class=\"token function\">mkdir</span> teamspeak</pre></td></tr><tr><td data-num=\"2\"></td><td data-command=\"[teamspeak@Starling] $\"></td><td><pre><span class=\"token function\">mv</span>  teamspeak3-server_linux_amd64 teamspeak-rf </pre></td></tr><tr><td data-num=\"3\"></td><td data-command=\"[teamspeak@Starling] $\"></td><td><pre><span class=\"token function\">rm</span> <span class=\"token parameter variable\">-rf</span> teamspeak3-server_linux_amd64</pre></td></tr><tr><td data-num=\"4\"></td><td data-command=\"[teamspeak@Starling] $\"></td><td><pre><span class=\"token builtin class-name\">cd</span> teamspeak</pre></td></tr></table></figure><h3 id=\"启动服务端\"><a class=\"anchor\" href=\"#启动服务端\">#</a> 启动服务端</h3>\n<h4 id=\"同意许可协议\"><a class=\"anchor\" href=\"#同意许可协议\">#</a> 同意许可协议</h4>\n<figure class=\"highlight bash\"><figcaption data-lang=\"bash\"><span>XShell</span></figcaption><table><tr><td data-num=\"1\"></td><td data-command=\"\"></td><td><pre><span class=\"token comment\"># 没什么好说的，就是同意许可协议</span></pre></td></tr><tr><td data-num=\"2\"></td><td data-command=\"[teamspeak@Starling] $\"></td><td><pre><span class=\"token function\">touch</span> .ts3server_license_accepted</pre></td></tr></table></figure><h4 id=\"启动与配置\"><a class=\"anchor\" href=\"#启动与配置\">#</a> 启动与配置</h4>\n<figure class=\"highlight bash\"><figcaption data-lang=\"bash\"><span>XShell</span></figcaption><table><tr><td data-num=\"1\"></td><td data-command=\"\"></td><td><pre><span class=\"token comment\"># 启动服务端</span></pre></td></tr><tr><td data-num=\"2\"></td><td data-command=\"[teamspeak@Starling] $\"></td><td><pre>./ts3server_startscript.sh start</pre></td></tr></table></figure><p><mark>第一次启动，会显示包括 token 在内的重要的信息，记得保存！！！</mark></p>\n<p>然后 <code>Ctrl</code> + <code>C</code>  退出。</p>\n<p><img data-src=\"1.png\" alt=\"记得保存\" /></p>\n<h4 id=\"开放端口\"><a class=\"anchor\" href=\"#开放端口\">#</a> 开放端口</h4>\n<p><mark>我们需要为服务器开放一些端口，否则无法与客户端进行通讯。</mark></p>\n<p>以下是端口列表，不仅仅要在服务器开放，还要在云服务提供商的控制台的安全组中开放。</p>\n<table>\n<thead>\n<tr>\n<th>端口</th>\n<th>协议</th>\n<th>说明</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>9987</td>\n<td>UDP</td>\n<td>TeamSpeak 语音服务端口</td>\n</tr>\n<tr>\n<td>10011</td>\n<td>TCP</td>\n<td>TeamSpeak ServerQuery raw 端口</td>\n</tr>\n<tr>\n<td>10022</td>\n<td>TCP</td>\n<td>TeamSpeak ServerQuery SSH 端口</td>\n</tr>\n<tr>\n<td>30033</td>\n<td>TCP</td>\n<td>TeamSpeak 文件传输端口</td>\n</tr>\n<tr>\n<td>41144</td>\n<td>TCP</td>\n<td>TSDNS 服务器端口</td>\n</tr>\n<tr>\n<td>58913</td>\n<td>TCP</td>\n<td>机器人网站后台端口（不开无所谓）</td>\n</tr>\n<tr>\n<td>3000</td>\n<td>TCP</td>\n<td>网易云 api 后台端口（后面要用，先放开这个端口）</td>\n</tr>\n</tbody>\n</table>\n<p>在服务器开放端口：</p>\n<figure class=\"highlight bash\"><figcaption data-lang=\"bash\"><span>XShell</span></figcaption><table><tr><td data-num=\"1\"></td><td data-command=\"[root@Starling] $\"></td><td><pre>firewall-cmd <span class=\"token parameter variable\">--zone</span><span class=\"token operator\">=</span>public --add-port<span class=\"token operator\">=</span><span class=\"token number\">9987</span>/udp <span class=\"token parameter variable\">--permanent</span> <span class=\"token operator\">&amp;&amp;</span> firewall-cmd <span class=\"token parameter variable\">--reloa</span></pre></td></tr><tr><td data-num=\"2\"></td><td data-command=\"[root@Starling] $\"></td><td><pre>firewall-cmd <span class=\"token parameter variable\">--zone</span><span class=\"token operator\">=</span>public --add-port<span class=\"token operator\">=</span><span class=\"token number\">10011</span>/tcp <span class=\"token parameter variable\">--permanent</span> <span class=\"token operator\">&amp;&amp;</span> firewall-cmd <span class=\"token parameter variable\">--reloa</span></pre></td></tr><tr><td data-num=\"3\"></td><td data-command=\"[root@Starling] $\"></td><td><pre>firewall-cmd <span class=\"token parameter variable\">--zone</span><span class=\"token operator\">=</span>public --add-port<span class=\"token operator\">=</span><span class=\"token number\">10022</span>/tcp <span class=\"token parameter variable\">--permanent</span> <span class=\"token operator\">&amp;&amp;</span> firewall-cmd <span class=\"token parameter variable\">--reloa</span></pre></td></tr><tr><td data-num=\"4\"></td><td data-command=\"[root@Starling] $\"></td><td><pre>firewall-cmd <span class=\"token parameter variable\">--zone</span><span class=\"token operator\">=</span>public --add-port<span class=\"token operator\">=</span><span class=\"token number\">30033</span>/tcp <span class=\"token parameter variable\">--permanent</span> <span class=\"token operator\">&amp;&amp;</span> firewall-cmd <span class=\"token parameter variable\">--reloa</span></pre></td></tr><tr><td data-num=\"5\"></td><td data-command=\"[root@Starling] $\"></td><td><pre>firewall-cmd <span class=\"token parameter variable\">--zone</span><span class=\"token operator\">=</span>public --add-port<span class=\"token operator\">=</span><span class=\"token number\">41144</span>/tcp <span class=\"token parameter variable\">--permanent</span> <span class=\"token operator\">&amp;&amp;</span> firewall-cmd <span class=\"token parameter variable\">--reloa</span></pre></td></tr><tr><td data-num=\"6\"></td><td data-command=\"[root@Starling] $\"></td><td><pre>firewall-cmd <span class=\"token parameter variable\">--zone</span><span class=\"token operator\">=</span>public --add-port<span class=\"token operator\">=</span><span class=\"token number\">3000</span>/tcp <span class=\"token parameter variable\">--permanent</span> <span class=\"token operator\">&amp;&amp;</span> firewall-cmd <span class=\"token parameter variable\">--reloa</span></pre></td></tr></table></figure><p>在安全组开放端口：</p>\n<p><img data-src=\"2.png\" alt=\"安全组\" /></p>\n<h4 id=\"设置开机自启\"><a class=\"anchor\" href=\"#设置开机自启\">#</a> 设置开机自启</h4>\n<p>注意使用 root 账号。</p>\n<figure class=\"highlight bash\"><figcaption data-lang=\"bash\"><span>XShell</span></figcaption><table><tr><td data-num=\"1\"></td><td data-command=\"\"></td><td><pre><span class=\"token comment\"># 新建 teamspeak.service</span></pre></td></tr><tr><td data-num=\"2\"></td><td data-command=\"[root@Starling] $\"></td><td><pre><span class=\"token function\">vim</span> /etc/systemd/system/teamspeak.service</pre></td></tr></table></figure><p>然后 <code>i</code>  进入 INSERT 模式，写文件：</p>\n<pre><code>[Unit]\nDescription=Teamspeak Service\nWants=network.target\n\n[Service]\nWorkingDirectory=/home/teamspeak\nExecStart=/home/teamspeak/teamspeak/ts3server_minimal_runscript.sh\nExecStop=/home/teamspeak/teamspeak/ts3server_startscript.sh stop\nExecReload=/home/teamspeak/teamspeak/ts3server_startscript.sh restart\nRestart=always\nRestartSec=15\n \n[Install]\nWantedBy=multi-user.target\n</code></pre>\n<p>然后 <code>Esc</code> ， <code>:wq!</code>  强制保存并退出。</p>\n<figure class=\"highlight bash\"><figcaption data-lang=\"bash\"><span>XShell</span></figcaption><table><tr><td data-num=\"1\"></td><td data-command=\"\"></td><td><pre><span class=\"token comment\"># 更新配置</span></pre></td></tr><tr><td data-num=\"2\"></td><td data-command=\"[root@Starling] $\"></td><td><pre>systemctldaemon-reload</pre></td></tr><tr><td data-num=\"3\"></td><td data-command=\"\"></td><td><pre></pre></td></tr><tr><td data-num=\"4\"></td><td data-command=\"\"></td><td><pre><span class=\"token comment\"># 设置开机启动</span></pre></td></tr><tr><td data-num=\"5\"></td><td data-command=\"[root@Starling] $\"></td><td><pre>systemctl <span class=\"token builtin class-name\">enable</span> teamspeak.service</pre></td></tr><tr><td data-num=\"6\"></td><td data-command=\"\"></td><td><pre></pre></td></tr><tr><td data-num=\"7\"></td><td data-command=\"\"></td><td><pre><span class=\"token comment\"># 启动服务</span></pre></td></tr><tr><td data-num=\"8\"></td><td data-command=\"[root@Starling] $\"></td><td><pre>systemctl start teamspeak.service</pre></td></tr><tr><td data-num=\"9\"></td><td data-command=\"\"></td><td><pre></pre></td></tr><tr><td data-num=\"10\"></td><td data-command=\"\"></td><td><pre><span class=\"token comment\"># 查看状态，如果有 active (running) 说明成功了</span></pre></td></tr><tr><td data-num=\"11\"></td><td data-command=\"[root@Starling] $\"></td><td><pre>systemctl status teamspeak.service</pre></td></tr></table></figure><h3 id=\"客户端连接\"><a class=\"anchor\" href=\"#客户端连接\">#</a> 客户端连接</h3>\n<p>这个时候就可以去官网设置服务器别名了，或者也可以直接裸连服务器地址。</p>\n<p>连接后使用上面保存的 token 设置自己为超级管理员。</p>\n<p>随后自定义各种设置。</p>\n<h2 id=\"部署ts3audiobot并添加网易云插件\"><a class=\"anchor\" href=\"#部署ts3audiobot并添加网易云插件\">#</a> 部署 TS3AudioBot 并添加网易云插件</h2>\n<h3 id=\"安装ffmpeg\"><a class=\"anchor\" href=\"#安装ffmpeg\">#</a> 安装 ffmpeg</h3>\n<figure class=\"highlight bash\"><figcaption data-lang=\"bash\"><span>XShell</span></figcaption><table><tr><td data-num=\"1\"></td><td data-command=\"[root@Starling] $\"></td><td><pre>yum <span class=\"token parameter variable\">-y</span> <span class=\"token function\">install</span> epel-release</pre></td></tr><tr><td data-num=\"2\"></td><td data-command=\"[root@Starling] $\"></td><td><pre><span class=\"token function\">rpm</span> <span class=\"token parameter variable\">-Uvh</span> http://li.nux.ro/download/nux/dextop/el7/x86_64/nux-dextop-release-0-5.el7.nux.noarch.rpm</pre></td></tr><tr><td data-num=\"3\"></td><td data-command=\"[root@Starling] $\"></td><td><pre>yum <span class=\"token parameter variable\">-y</span> <span class=\"token function\">install</span> ffmpeg opus-devel</pre></td></tr></table></figure><h3 id=\"下载ts3audiobot本体与插件并解压\"><a class=\"anchor\" href=\"#下载ts3audiobot本体与插件并解压\">#</a> 下载 TS3AudioBot 本体与插件并解压</h3>\n<p><mark>不要下载官方的，因为官方给的 linux 版编译环境有问题导致后面不能正常加载插件</mark></p>\n<p>下载<span class=\"exturl\" data-url=\"aHR0cHM6Ly9naXRodWIuY29tL1pIQU5HVElBTllBTzEvVFMzQXVkaW9Cb3QtTmV0RWFzZUNsb3VkbXVzaWMtcGx1Z2luL3JlbGVhc2VzL2Rvd25sb2FkLzEuMS4wL3dpdGguVFMzQm90LmxpbnV4LXg2NC56aXA=\"> ZHANGTIAOYAO1 重构后的版本</span>与<span class=\"exturl\" data-url=\"aHR0cHM6Ly9naXRodWIuY29tL0ZpdmVIYWlyL1RTM0F1ZGlvQm90LU5ldEVhc2VDbG91ZG11c2ljLXBsdWdpbi1VTk0=\"> FiveHair 修改后的网易云插件</span>。</p>\n<p>命令行下载：</p>\n<figure class=\"highlight bash\"><figcaption data-lang=\"bash\"><span>XShell</span></figcaption><table><tr><td data-num=\"1\"></td><td data-command=\"\"></td><td><pre><span class=\"token comment\"># 切换 teamspeak 账号</span></pre></td></tr><tr><td data-num=\"2\"></td><td data-command=\"[root@Starling] $\"></td><td><pre><span class=\"token function\">su</span> teamspeak</pre></td></tr><tr><td data-num=\"3\"></td><td data-command=\"[teamspeak@Starling] $\"></td><td><pre><span class=\"token builtin class-name\">cd</span> ~</pre></td></tr><tr><td data-num=\"4\"></td><td data-command=\"[teamspeak@Starling] $\"></td><td><pre><span class=\"token function\">wget</span> https://github.com/ZHANGTIANYAO1/TS3AudioBot-NetEaseCloudmusic-plugin/releases/download/1.1.0/with.TS3Bot.linux-x64.zip</pre></td></tr><tr><td data-num=\"5\"></td><td data-command=\"[teamspeak@Starling] $\"></td><td><pre><span class=\"token function\">wget</span> https://github.com/FiveHair/TS3AudioBot-NetEaseCloudmusic-plugin-UNM/releases/download/2.0.3.1/YunPlugin-UNM-2.0.3.1.zip</pre></td></tr></table></figure><p>解压本体与插件并拷贝插件至本体的 plugins 目录：</p>\n<figure class=\"highlight bash\"><figcaption data-lang=\"bash\"><span>XShell</span></figcaption><table><tr><td data-num=\"1\"></td><td data-command=\"[teamspeak@Starling] $\"></td><td><pre><span class=\"token function\">unzip</span> with.TS3Bot.linux-x64.zip</pre></td></tr><tr><td data-num=\"2\"></td><td data-command=\"[teamspeak@Starling] $\"></td><td><pre><span class=\"token function\">mv</span> linux-x64 TS3AudioBot</pre></td></tr><tr><td data-num=\"3\"></td><td data-command=\"[teamspeak@Starling] $\"></td><td><pre><span class=\"token function\">unzip</span> YunPlugin-UNM-2.0.3.1.zip</pre></td></tr><tr><td data-num=\"4\"></td><td data-command=\"[teamspeak@Starling] $\"></td><td><pre><span class=\"token builtin class-name\">cd</span> TS3AudioBot/plugins</pre></td></tr><tr><td data-num=\"5\"></td><td data-command=\"[teamspeak@Starling] $\"></td><td><pre><span class=\"token function\">rm</span> *</pre></td></tr><tr><td data-num=\"6\"></td><td data-command=\"[teamspeak@Starling] $\"></td><td><pre><span class=\"token builtin class-name\">cd</span> ~</pre></td></tr><tr><td data-num=\"7\"></td><td data-command=\"[teamspeak@Starling] $\"></td><td><pre><span class=\"token function\">mv</span> YunPlugin-UNM.dll TS3AudioBot/plugins/</pre></td></tr><tr><td data-num=\"8\"></td><td data-command=\"[teamspeak@Starling] $\"></td><td><pre><span class=\"token function\">mv</span> YunSettings.ini TS3AudioBot/plugins/</pre></td></tr></table></figure><h3 id=\"配置ts3audiobot启动\"><a class=\"anchor\" href=\"#配置ts3audiobot启动\">#</a> 配置 TS3AudioBot 启动</h3>\n<figure class=\"highlight bash\"><figcaption data-lang=\"bash\"><span>XShell</span></figcaption><table><tr><td data-num=\"1\"></td><td data-command=\"[teamspeak@Starling] $\"></td><td><pre><span class=\"token builtin class-name\">cd</span> TS3AudioBot</pre></td></tr><tr><td data-num=\"2\"></td><td data-command=\"[teamspeak@Starling] $\"></td><td><pre><span class=\"token function\">chmod</span> <span class=\"token number\">755</span> TS3AudioBot</pre></td></tr><tr><td data-num=\"3\"></td><td data-command=\"[teamspeak@Starling] $\"></td><td><pre>./TS3AudioBot</pre></td></tr></table></figure><p>随后根据引导设置管理员的 uid（在客户端上面 “权限” 菜单中打开 “所有客户端列表” 可以看到服务器所有人的 uid）、服务器 ip、密码等。</p>\n<p>然后直接 <code>Ctrl</code> + <code>C</code>  结束进程。</p>\n<h3 id=\"设置开机自启-2\"><a class=\"anchor\" href=\"#设置开机自启-2\">#</a> 设置开机自启</h3>\n<p>注意切换 root 账号：</p>\n<figure class=\"highlight bash\"><figcaption data-lang=\"bash\"><span>XShell</span></figcaption><table><tr><td data-num=\"1\"></td><td data-command=\"\"></td><td><pre><span class=\"token comment\"># ts3audiobot.service</span></pre></td></tr><tr><td data-num=\"2\"></td><td data-command=\"[root@Starling] $\"></td><td><pre><span class=\"token function\">vim</span> /etc/systemd/system/ts3audiobot.service</pre></td></tr></table></figure><p>然后 <code>i</code>  进入 INSERT 模式，写文件：</p>\n<pre><code>[Unit]\nDescription=TS3AudioBot\nAfter=teamspeak.service\n\n[Service]\nWorkingDirectory=/home/teamspeak/TS3AudioBot/\nExecStart=/home/teamspeak/TS3AudioBot/TS3AudioBot\nRestart=always\nRestartSec=15\n\n[Install]\nWantedBy=multi-user.target\n</code></pre>\n<p>然后 <code>Esc</code> ， <code>:wq!</code>  强制保存并退出。</p>\n<figure class=\"highlight bash\"><figcaption data-lang=\"bash\"><span>XShell</span></figcaption><table><tr><td data-num=\"1\"></td><td data-command=\"\"></td><td><pre><span class=\"token comment\"># 更新配置</span></pre></td></tr><tr><td data-num=\"2\"></td><td data-command=\"[root@Starling] $\"></td><td><pre>systemctldaemon-reload</pre></td></tr><tr><td data-num=\"3\"></td><td data-command=\"\"></td><td><pre></pre></td></tr><tr><td data-num=\"4\"></td><td data-command=\"\"></td><td><pre><span class=\"token comment\"># 设置开机启动</span></pre></td></tr><tr><td data-num=\"5\"></td><td data-command=\"[root@Starling] $\"></td><td><pre>systemctl <span class=\"token builtin class-name\">enable</span> ts3audiobot.service</pre></td></tr><tr><td data-num=\"6\"></td><td data-command=\"\"></td><td><pre></pre></td></tr><tr><td data-num=\"7\"></td><td data-command=\"\"></td><td><pre><span class=\"token comment\"># 启动服务</span></pre></td></tr><tr><td data-num=\"8\"></td><td data-command=\"[root@Starling] $\"></td><td><pre>systemctl start ts3audiobot.service</pre></td></tr><tr><td data-num=\"9\"></td><td data-command=\"\"></td><td><pre></pre></td></tr><tr><td data-num=\"10\"></td><td data-command=\"\"></td><td><pre><span class=\"token comment\"># 查看状态，如果有 active (running) 说明成功了</span></pre></td></tr><tr><td data-num=\"11\"></td><td data-command=\"[root@Starling] $\"></td><td><pre>systemctl status ts3audiobot.service</pre></td></tr></table></figure><h2 id=\"部署网易云api\"><a class=\"anchor\" href=\"#部署网易云api\">#</a> 部署网易云 API</h2>\n<h3 id=\"安装git\"><a class=\"anchor\" href=\"#安装git\">#</a> 安装 git</h3>\n<figure class=\"highlight bash\"><figcaption data-lang=\"bash\"><span>XShell</span></figcaption><table><tr><td data-num=\"1\"></td><td data-command=\"[root@Starling] $\"></td><td><pre><span class=\"token function\">sudo</span> yum <span class=\"token function\">install</span> <span class=\"token parameter variable\">-y</span> <span class=\"token function\">git</span></pre></td></tr><tr><td data-num=\"2\"></td><td data-command=\"\"></td><td><pre><span class=\"token comment\"># 设置用户名</span></pre></td></tr><tr><td data-num=\"3\"></td><td data-command=\"[root@Starling] $\"></td><td><pre><span class=\"token function\">git</span> config <span class=\"token parameter variable\">--global</span> user.name <span class=\"token string\">\"名字\"</span></pre></td></tr><tr><td data-num=\"4\"></td><td data-command=\"\"></td><td><pre><span class=\"token comment\"># 设置邮箱</span></pre></td></tr><tr><td data-num=\"5\"></td><td data-command=\"[root@Starling] $\"></td><td><pre><span class=\"token function\">git</span> config <span class=\"token parameter variable\">--global</span> user.email <span class=\"token string\">\"邮箱\"</span></pre></td></tr></table></figure><h3 id=\"安装nodejs和npm\"><a class=\"anchor\" href=\"#安装nodejs和npm\">#</a> 安装 Node.js 和 npm</h3>\n<figure class=\"highlight bash\"><figcaption data-lang=\"bash\"><span>XShell</span></figcaption><table><tr><td data-num=\"1\"></td><td data-command=\"[root@Starling] $\"></td><td><pre><span class=\"token function\">sudo</span> yum <span class=\"token function\">install</span> <span class=\"token parameter variable\">-y</span> nodejs</pre></td></tr><tr><td data-num=\"2\"></td><td data-command=\"[root@Starling] $\"></td><td><pre><span class=\"token function\">sudo</span> yum <span class=\"token function\">install</span> <span class=\"token parameter variable\">-y</span> <span class=\"token function\">npm</span></pre></td></tr></table></figure><h3 id=\"搭建api\"><a class=\"anchor\" href=\"#搭建api\">#</a> 搭建 API</h3>\n<p>注意还是切换到 teamspeak 账号：</p>\n<figure class=\"highlight bash\"><figcaption data-lang=\"bash\"><span>XShell</span></figcaption><table><tr><td data-num=\"1\"></td><td data-command=\"[root@Starling] $\"></td><td><pre><span class=\"token function\">su</span> teamspeak</pre></td></tr><tr><td data-num=\"2\"></td><td data-command=\"[teamspeak@Starling] $\"></td><td><pre><span class=\"token builtin class-name\">cd</span> ~</pre></td></tr><tr><td data-num=\"3\"></td><td data-command=\"[teamspeak@Starling] $\"></td><td><pre><span class=\"token function\">sudo</span> <span class=\"token function\">git</span> clone git@gitlab.com:Binaryify/NeteaseCloudMusicApi.git</pre></td></tr></table></figure><p><mark>由于网易云的赶尽杀绝，大部分 API 都寄了，而这个其实也寄了。但是虽然 github 上改仓库删除归档了，我们依旧能在 gitlab 找到全部源码。</mark></p>\n<figure class=\"highlight bash\"><figcaption data-lang=\"bash\"><span>XShell</span></figcaption><table><tr><td data-num=\"1\"></td><td data-command=\"[teamspeak@Starling] $\"></td><td><pre><span class=\"token builtin class-name\">cd</span> NeteaseCloudMusicApi</pre></td></tr><tr><td data-num=\"2\"></td><td data-command=\"[teamspeak@Starling] $\"></td><td><pre><span class=\"token function\">sudo</span> <span class=\"token function\">npm</span> <span class=\"token function\">install</span></pre></td></tr><tr><td data-num=\"3\"></td><td data-command=\"[teamspeak@Starling] $\"></td><td><pre><span class=\"token function\">sudo</span> <span class=\"token function\">node</span> app.js</pre></td></tr></table></figure><p>此时显示 <code>server running ...</code>  即为配置成功，按 <code>Ctrl</code> + <code>C</code> ，退出。</p>\n<h3 id=\"设置开机自启-3\"><a class=\"anchor\" href=\"#设置开机自启-3\">#</a> 设置开机自启</h3>\n<p>注意切换 root 用户：</p>\n<figure class=\"highlight bash\"><figcaption data-lang=\"bash\"><span>XShell</span></figcaption><table><tr><td data-num=\"1\"></td><td data-command=\"\"></td><td><pre><span class=\"token comment\"># netease.service</span></pre></td></tr><tr><td data-num=\"2\"></td><td data-command=\"[root@Starling] $\"></td><td><pre><span class=\"token function\">vim</span> /etc/systemd/system/netease.service</pre></td></tr></table></figure><p>然后 <code>i</code>  进入 INSERT 模式，写文件：</p>\n<pre><code>[Unit]\nDescription=Netease Cloud Music API Service\nAfter=network.target\n\n[Service]\nWorkingDirectory=/home/teamspeak/NeteaseCloudMusicApi/\nExecStart=/usr/bin/node /home/teamspeak/NeteaseCloudMusicApi/app.js\nRestart=always\nRestartSec=15\n\n[Install]\nWantedBy=multi-user.target\n</code></pre>\n<p>然后 <code>Esc</code> ， <code>:wq!</code>  强制保存并退出。</p>\n<figure class=\"highlight bash\"><figcaption data-lang=\"bash\"><span>XShell</span></figcaption><table><tr><td data-num=\"1\"></td><td data-command=\"\"></td><td><pre><span class=\"token comment\"># 更新配置</span></pre></td></tr><tr><td data-num=\"2\"></td><td data-command=\"[root@Starling] $\"></td><td><pre>systemctldaemon-reload</pre></td></tr><tr><td data-num=\"3\"></td><td data-command=\"\"></td><td><pre></pre></td></tr><tr><td data-num=\"4\"></td><td data-command=\"\"></td><td><pre><span class=\"token comment\"># 设置开机启动</span></pre></td></tr><tr><td data-num=\"5\"></td><td data-command=\"[root@Starling] $\"></td><td><pre>systemctl <span class=\"token builtin class-name\">enable</span> netease.service</pre></td></tr><tr><td data-num=\"6\"></td><td data-command=\"\"></td><td><pre></pre></td></tr><tr><td data-num=\"7\"></td><td data-command=\"\"></td><td><pre><span class=\"token comment\"># 启动服务</span></pre></td></tr><tr><td data-num=\"8\"></td><td data-command=\"[root@Starling] $\"></td><td><pre>systemctl start netease.service</pre></td></tr><tr><td data-num=\"9\"></td><td data-command=\"\"></td><td><pre></pre></td></tr><tr><td data-num=\"10\"></td><td data-command=\"\"></td><td><pre><span class=\"token comment\"># 查看状态，如果有 active (running) 说明成功了</span></pre></td></tr><tr><td data-num=\"11\"></td><td data-command=\"[root@Starling] $\"></td><td><pre>systemctl status netease.service</pre></td></tr></table></figure><h2 id=\"将插件与api连接\"><a class=\"anchor\" href=\"#将插件与api连接\">#</a> 将插件与 API 连接</h2>\n<p>注意还是切回 teamspeak 账号：</p>\n<figure class=\"highlight bash\"><figcaption data-lang=\"bash\"><span>XShell</span></figcaption><table><tr><td data-num=\"1\"></td><td data-command=\"[teamspeak@Starling] $\"></td><td><pre><span class=\"token builtin class-name\">cd</span> ~</pre></td></tr><tr><td data-num=\"2\"></td><td data-command=\"[teamspeak@Starling] $\"></td><td><pre><span class=\"token builtin class-name\">cd</span> TS3AudioBot/plugins</pre></td></tr><tr><td data-num=\"3\"></td><td data-command=\"[teamspeak@Starling] $\"></td><td><pre><span class=\"token function\">vim</span> YunSettings.ini</pre></td></tr></table></figure><p>将链接修改为本地：</p>\n<pre><code># 如果原本等号后面有东西就删掉\nWangYiYunAPI_Address = http://localhost:3000\n</code></pre>\n<h2 id=\"设置机器人指令权限\"><a class=\"anchor\" href=\"#设置机器人指令权限\">#</a> 设置机器人指令权限</h2>\n<p>设置谁能操控机器人谁能点歌，在 <code>/home/teamspeak/TS3AudioBot</code>  目录下的 <code>rights.toml</code>  中有详细的说明与设置方法。</p>\n<h2 id=\"启动机器人\"><a class=\"anchor\" href=\"#启动机器人\">#</a> 启动机器人</h2>\n<p>之后的操作仅在客户端就能完成。</p>\n<p>聊天框输入 <code>!plugin list</code> ，找到网易云插件（状态应该是 RDY 就绪）的编号（假设是 #0）。</p>\n<p>输入 <code>!plugin load 0</code> （后面数字得看编号）加载插件。</p>\n<p>然后再查看插件列表，网易云插件的状态应该为（+ON 运行）</p>\n<p>之后输入 <code>!yun login</code>  后根据机器人的头像与简洁设置登录网易云（请给机器人管理员权限）。</p>\n<p>大功告成！</p>\n<p><img data-src=\"3.png\" alt=\"测试\" /></p>\n",
            "tags": [
                "计算机科学",
                "杂项",
                "Linux",
                "TeamSpeak",
                "NetEaseMusic"
            ]
        },
        {
            "id": "https://www.starlinglin.top/computer-science/Linux-note/%E6%A4%8B%E9%B8%9FLinux%E7%AC%94%E8%AE%B0%20%EF%BC%830%EF%BC%9A%E5%AD%A6%E4%B9%A0Linux%E5%89%8D/",
            "url": "https://www.starlinglin.top/computer-science/Linux-note/%E6%A4%8B%E9%B8%9FLinux%E7%AC%94%E8%AE%B0%20%EF%BC%830%EF%BC%9A%E5%AD%A6%E4%B9%A0Linux%E5%89%8D/",
            "title": "椋鸟Linux笔记#0：学习Linux前",
            "date_published": "2024-05-24T12:55:21.000Z",
            "content_html": "<div class=\"note warning\">\n<p>本系列暴死，不会更新了。</p>\n</div>\n<div class=\"note info\">\n<p>该系列为本人的学习笔记，主要由本人整理书写而成。部分内容来自教材、视频课程等，不能保证完全原创性。</p>\n</div>\n<p>萌新的学习笔记，写错了恳请斧正。</p>\n<h3 id=\"关于linux\"><a class=\"anchor\" href=\"#关于linux\">#</a> 关于 Linux</h3>\n<p>Linux 是一种开源操作系统，其核心由林纳斯・托瓦兹于 1991 年开发，基于 UNIX 设计理念。Linux 内核本身仅是操作系统的核心部分，负责管理硬件资源，而完整的 Linux 系统还包括工具和库，这些通常由 GNU 计划提供。因此，完整的系统经常被称为 “GNU/Linux”。</p>\n<p>Linux 有多种发行版，每种都有自己的软件库和管理工具，例如 Ubuntu、Fedora 和 Debian 等。这些发行版适应了从个人桌面计算到服务器，再到嵌入式系统等不同的使用场景。</p>\n<p>Linux 广泛应用于服务器、超级计算机、网络设备，以及日益增长的移动设备和家庭设备中，特别是其在 Android 操作系统的核心组成部分中的使用，使其成为世界上应用最广泛的操作系统之一。</p>\n<h3 id=\"linux环境的搭建\"><a class=\"anchor\" href=\"#linux环境的搭建\">#</a> Linux 环境的搭建</h3>\n<p>我们自己搭建 Linux 环境一般有下面几种方法：</p>\n<h4 id=\"直接安装linux系统\"><a class=\"anchor\" href=\"#直接安装linux系统\">#</a> 直接安装 Linux 系统</h4>\n<p>直接将系统安装到主机上使用，就像我们使用 Windows 那样。</p>\n<p>但是这样非常不方便（哪怕是安装为双系统或者多系统），而且后面网络编程时不利于体验通信。</p>\n<h4 id=\"安装在虚拟机上\"><a class=\"anchor\" href=\"#安装在虚拟机上\">#</a> 安装在虚拟机上</h4>\n<p>本地使用 VMware、VirtualBox 等虚拟机软件，将 Linux 系统安装到虚拟机中。<br />\n这样使用较为方便，但是虚拟机网络需配置为桥接，也不利于后面网络编程。</p>\n<h4 id=\"安装为wsl2子系统\"><a class=\"anchor\" href=\"#安装为wsl2子系统\">#</a> 安装为 WSL2 子系统</h4>\n<p>利用 Windows11 提供的新特性，部署 WSL2 后直接在 MSStore 中安装相应版本的 Linux 系统。<br />\n这样使用非常方便，但是缺点和虚拟机类似。</p>\n<h4 id=\"使用云服务\"><a class=\"anchor\" href=\"#使用云服务\">#</a> 使用云服务</h4>\n<p>在云服务提供商（阿里云、百度云、腾讯云等处购买云服务器，然后本地通过 XShell 等软件或者直接控制台 ssh 链接到服务器即可。从云服务提供商处获得的云服务器一般是自带公网 IPv4 点，这是我们自己难以做到的。</p>\n<p>优点是非常方便使用和管理，而且利于后面网络部分的学习。缺点是价格一般较高（哪怕学生第一年的超优惠价格也是 99 块 1 年）（但是可以白嫖）。</p>\n<details class=\"primary\"><summary>白嫖云服务（不是广告）</summary><div>\n<div class=\"note info\">\n<p>下面的白嫖方法应当是有时效性的活动，请注意本内容写于 2024 年 5 月 21 日。</p>\n</div>\n<p>阿里云有为学生提供免费的云服务，能白领 7 个月的 Linux 服务器，活动网页如下：</p>\n<p><div class=\"links\"><div class=\"item\" title=\"阿里云学生权益\" style=\"--block-color:#39c5bb;\"><span class=\"exturl image\" data-url=\"aHR0cHM6Ly9kZXZlbG9wZXIuYWxpeXVuLmNvbS9wbGFuL3N0dWRlbnQ=\" data-background-image=\"/images/404.png\"></span>\n          <div class=\"info\">\n          <span class=\"exturl title\" data-url=\"aHR0cHM6Ly9kZXZlbG9wZXIuYWxpeXVuLmNvbS9wbGFuL3N0dWRlbnQ=\">阿里云学生权益</span>\n          <p class=\"desc\">https://developer.aliyun.com/plan/student</p>\n          </div></div></div></p>\n<p>这个只要认证学生身份就能领一个月，完成 Clouder 认证就能续领 6 个月（非常简单跟着提示做就行）。</p>\n</div></details>\n<p>购买完云服务后我们应该做的是：</p>\n<ol>\n<li>在云服务商的控制台查看我们服务器的公网 IP 地址，保存或者记下来。</li>\n<li>设置 root 用户的密码。</li>\n</ol>\n<h3 id=\"直接控制台连接远程服务器\"><a class=\"anchor\" href=\"#直接控制台连接远程服务器\">#</a> 直接控制台连接远程服务器</h3>\n<p>我们打开电脑的控制台，直接连接服务器我们可以输入：</p>\n<figure class=\"highlight bash\"><figcaption data-lang=\"bash\"></figcaption><table><tr><td data-num=\"1\"></td><td><pre><span class=\"token function\">ssh</span> root@114.114.114.114</pre></td></tr><tr><td data-num=\"2\"></td><td><pre><span class=\"token comment\"># 注意这里 root 是指管理员账户，后面是服务器的公网 IP 地址</span></pre></td></tr></table></figure><p>随后按照提示输入密码即可。</p>\n<p>或者我们只输入公网 IP，随后根据提示输入用户名和密码：</p>\n<figure class=\"highlight bash\"><figcaption data-lang=\"bash\"></figcaption><table><tr><td data-num=\"1\"></td><td><pre><span class=\"token function\">ssh</span> <span class=\"token number\">114.114</span>.114.114</pre></td></tr><tr><td data-num=\"2\"></td><td><pre><span class=\"token comment\"># 后面是服务器的公网 IP 地址</span></pre></td></tr></table></figure><h3 id=\"使用xshell连接远程服务器\"><a class=\"anchor\" href=\"#使用xshell连接远程服务器\">#</a> 使用 XShell 连接远程服务器</h3>\n<p>使用像 XShell 这样的软件连接，功能更多更强大，可以方便以后的操作。</p>\n<p>XShell 的下载官网是：</p>\n<p><div class=\"links\"><div class=\"item\" title=\"Xshell\" style=\"--block-color:#39c5bb;\"><span class=\"exturl image\" data-url=\"aHR0cHM6Ly93d3cueHNoZWxsLmNvbS96aC94c2hlbGwv\" data-background-image=\"/images/404.png\"></span>\n          <div class=\"info\">\n          <span class=\"exturl title\" data-url=\"aHR0cHM6Ly93d3cueHNoZWxsLmNvbS96aC94c2hlbGwv\">Xshell</span>\n          <p class=\"desc\">https://www.xshell.com/zh/xshell/</p>\n          </div></div></div></p>\n<p>使用 XShell 的话需要注意一些点：</p>\n<ol>\n<li>XShell 下允许使用复制和粘贴快捷键，复制是 <code>Ctrl</code> + <code>Insert</code> ，粘贴是 <code>Shift</code> + <code>Insert</code> 。</li>\n<li>要解决连接后出现警告 <code>The remote SSH server rejected X11 forwarding request.</code>  我们只需要执行代码 <code>yum install xorg-x11-xauth</code>  即可。</li>\n</ol>\n",
            "tags": [
                "计算机科学",
                "Linux笔记",
                "Linux"
            ]
        },
        {
            "id": "https://www.starlinglin.top/computer-science/Cpp-programme-note/%E6%A4%8B%E9%B8%9FC++%E7%AC%94%E8%AE%B0%20%EF%BC%833%EF%BC%9A%E7%B1%BB%E7%9A%84%E9%BB%98%E8%AE%A4%E6%88%90%E5%91%98%E5%87%BD%E6%95%B0/",
            "url": "https://www.starlinglin.top/computer-science/Cpp-programme-note/%E6%A4%8B%E9%B8%9FC++%E7%AC%94%E8%AE%B0%20%EF%BC%833%EF%BC%9A%E7%B1%BB%E7%9A%84%E9%BB%98%E8%AE%A4%E6%88%90%E5%91%98%E5%87%BD%E6%95%B0/",
            "title": "椋鸟C++笔记#3：类的默认成员函数",
            "date_published": "2024-05-24T11:23:01.000Z",
            "content_html": "<div class=\"note warning\">\n<p>本系列暴死，不会更新了。</p>\n</div>\n<div class=\"note info\">\n<p>该系列为本人的学习笔记，主要由本人整理书写而成。部分内容来自教材、视频课程等，不能保证完全原创性。</p>\n</div>\n<p>萌新的学习笔记，写错了恳请斧正。</p>\n<h3 id=\"类的默认成员函数\"><a class=\"anchor\" href=\"#类的默认成员函数\">#</a> 类的默认成员函数</h3>\n<p>我们写一个类，在类体中什么都不写，这样的类就叫<strong>空类</strong>。</p>\n<p>空类真的什么都没有吗？并不是的。</p>\n<p>类有六个默认成员函数，如果我们自己没有写这六个函数，类也会自己去补齐它们。</p>\n<ol>\n<li><strong>默认构造函数（Default Constructor）</strong> - 用于无参的初始化一个对象。</li>\n<li><strong>析构函数（Destructor）</strong> - 用于在对象生命周期结束时进行资源的回收等收尾工作。</li>\n<li><strong>拷贝构造函数（Copy Constructor）</strong> - 用于通过同类型的另一个对象来初始化新对象。</li>\n<li><strong>拷贝赋值运算符（Copy Assignment Operator）</strong> - 用于将一个对象的内容赋值给另一个同类型的对象。</li>\n<li><strong>移动构造函数（Move Constructor）</strong> - C++11 引入，用于通过 &quot;移动&quot; 而非拷贝另一个同类型的对象来初始化新对象。</li>\n<li><strong>移动赋值运算符（Move Assignment Operator）</strong> - C++11 引入，用于通过 &quot;移动&quot; 而非拷贝来将一个对象的内容赋值给另一个同类型的对象。</li>\n</ol>\n<p>其中后两个先不管，下面我们介绍一下前面几个函数。</p>\n<h3 id=\"构造函数constructor\"><a class=\"anchor\" href=\"#构造函数constructor\">#</a> 构造函数（Constructor）</h3>\n<p>我们先看这样一个类：</p>\n<figure class=\"highlight cpp\"><figcaption data-lang=\"C++\"></figcaption><table><tr><td data-num=\"1\"></td><td><pre><span class=\"token keyword\">class</span> <span class=\"token class-name\">Date</span></pre></td></tr><tr><td data-num=\"2\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"3\"></td><td><pre><span class=\"token keyword\">public</span><span class=\"token operator\">:</span></pre></td></tr><tr><td data-num=\"4\"></td><td><pre>    <span class=\"token keyword\">void</span> <span class=\"token function\">Init</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">int</span> y<span class=\"token punctuation\">,</span> <span class=\"token keyword\">int</span> m<span class=\"token punctuation\">,</span> <span class=\"token keyword\">int</span> d<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"5\"></td><td><pre>    <span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"6\"></td><td><pre>        m_year <span class=\"token operator\">=</span> y<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"7\"></td><td><pre>        m_month <span class=\"token operator\">=</span> m<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"8\"></td><td><pre>        m_day <span class=\"token operator\">=</span> d<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"9\"></td><td><pre>    <span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"10\"></td><td><pre>    </pre></td></tr><tr><td data-num=\"11\"></td><td><pre>    <span class=\"token keyword\">void</span> <span class=\"token function\">Print</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"12\"></td><td><pre>    <span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"13\"></td><td><pre>        cout <span class=\"token operator\">&lt;&lt;</span> m_year <span class=\"token operator\">&lt;&lt;</span> <span class=\"token string\">\"-\"</span> <span class=\"token operator\">&lt;&lt;</span> m_month <span class=\"token operator\">&lt;&lt;</span> <span class=\"token string\">\"-\"</span> <span class=\"token operator\">&lt;&lt;</span> m_day <span class=\"token operator\">&lt;&lt;</span> endl<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"14\"></td><td><pre>    <span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"15\"></td><td><pre>    </pre></td></tr><tr><td data-num=\"16\"></td><td><pre><span class=\"token keyword\">private</span><span class=\"token operator\">:</span></pre></td></tr><tr><td data-num=\"17\"></td><td><pre>    <span class=\"token keyword\">int</span> m_year<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"18\"></td><td><pre>    <span class=\"token keyword\">int</span> m_month<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"19\"></td><td><pre>    <span class=\"token keyword\">int</span> m_day<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"20\"></td><td><pre><span class=\"token punctuation\">&#125;</span><span class=\"token punctuation\">;</span></pre></td></tr></table></figure><p>对于这个日期类，我们每次要实例化一个对象时都需要这样先创建对象再使用 <code>Init</code>  函数完成初始化，非常的不方便。</p>\n<p>所以在 C++ 中，我们就有了构造函数。<strong>构造函数</strong>是一个特殊的成员函数，<mark>名字与类名相同</mark>。当我们创建对象时，其构造函数就会被自动调用，并且在对象的整个生命周期中只调用一次。</p>\n<p>比方说我们可以把上面的类改写成这样：</p>\n<figure class=\"highlight cpp\"><figcaption data-lang=\"C++\"></figcaption><table><tr><td data-num=\"1\"></td><td><pre><span class=\"token keyword\">class</span> <span class=\"token class-name\">Date</span></pre></td></tr><tr><td data-num=\"2\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"3\"></td><td><pre><span class=\"token keyword\">public</span><span class=\"token operator\">:</span></pre></td></tr><tr><td data-num=\"4\"></td><td><pre>    <span class=\"token function\">Date</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">int</span> y<span class=\"token punctuation\">,</span> <span class=\"token keyword\">int</span> m<span class=\"token punctuation\">,</span> <span class=\"token keyword\">int</span> d<span class=\"token punctuation\">)</span>\t<span class=\"token comment\">// 构造函数前面就不要加 void 了</span></pre></td></tr><tr><td data-num=\"5\"></td><td><pre>    <span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"6\"></td><td><pre>        m_year <span class=\"token operator\">=</span> y<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"7\"></td><td><pre>        m_month <span class=\"token operator\">=</span> m<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"8\"></td><td><pre>        m_day <span class=\"token operator\">=</span> d<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"9\"></td><td><pre>    <span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"10\"></td><td><pre>    </pre></td></tr><tr><td data-num=\"11\"></td><td><pre>    <span class=\"token keyword\">void</span> <span class=\"token function\">Print</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"12\"></td><td><pre>    <span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"13\"></td><td><pre>        cout <span class=\"token operator\">&lt;&lt;</span> m_year <span class=\"token operator\">&lt;&lt;</span> <span class=\"token string\">\"-\"</span> <span class=\"token operator\">&lt;&lt;</span> m_month <span class=\"token operator\">&lt;&lt;</span> <span class=\"token string\">\"-\"</span> <span class=\"token operator\">&lt;&lt;</span> m_day <span class=\"token operator\">&lt;&lt;</span> endl<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"14\"></td><td><pre>    <span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"15\"></td><td><pre>    </pre></td></tr><tr><td data-num=\"16\"></td><td><pre><span class=\"token keyword\">private</span><span class=\"token operator\">:</span></pre></td></tr><tr><td data-num=\"17\"></td><td><pre>    <span class=\"token keyword\">int</span> m_year<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"18\"></td><td><pre>    <span class=\"token keyword\">int</span> m_month<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"19\"></td><td><pre>    <span class=\"token keyword\">int</span> m_day<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"20\"></td><td><pre><span class=\"token punctuation\">&#125;</span><span class=\"token punctuation\">;</span></pre></td></tr></table></figure><h4 id=\"构造函数的特点\"><a class=\"anchor\" href=\"#构造函数的特点\">#</a> 构造函数的特点</h4>\n<ol>\n<li>\n<p>函数名与类名相同。</p>\n</li>\n<li>\n<p>没有返回值。</p>\n</li>\n<li>\n<p>对象实例化时编译器<strong>自动调用</strong>对应的构造函数。</p>\n</li>\n<li>\n<p>同样可以重载：</p>\n<figure class=\"highlight cpp\"><figcaption data-lang=\"C++\"></figcaption><table><tr><td data-num=\"1\"></td><td><pre><span class=\"token keyword\">class</span> <span class=\"token class-name\">Date</span></pre></td></tr><tr><td data-num=\"2\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"3\"></td><td><pre><span class=\"token keyword\">public</span><span class=\"token operator\">:</span></pre></td></tr><tr><td data-num=\"4\"></td><td><pre>    <span class=\"token function\">Date</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\t<span class=\"token comment\">// 无参</span></pre></td></tr><tr><td data-num=\"5\"></td><td><pre>    <span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"6\"></td><td><pre>        m_year <span class=\"token operator\">=</span> <span class=\"token number\">1900</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"7\"></td><td><pre>        m_month <span class=\"token operator\">=</span> <span class=\"token number\">1</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"8\"></td><td><pre>        m_day <span class=\"token operator\">=</span> <span class=\"token number\">1</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"9\"></td><td><pre>    <span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"10\"></td><td><pre></pre></td></tr><tr><td data-num=\"11\"></td><td><pre>    <span class=\"token function\">Date</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">int</span> y<span class=\"token punctuation\">,</span> <span class=\"token keyword\">int</span> m<span class=\"token punctuation\">,</span> <span class=\"token keyword\">int</span> d<span class=\"token punctuation\">)</span>\t<span class=\"token comment\">// 带参</span></pre></td></tr><tr><td data-num=\"12\"></td><td><pre>    <span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"13\"></td><td><pre>        m_year <span class=\"token operator\">=</span> y<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"14\"></td><td><pre>        m_month <span class=\"token operator\">=</span> m<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"15\"></td><td><pre>        m_day <span class=\"token operator\">=</span> d<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"16\"></td><td><pre>    <span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"17\"></td><td><pre></pre></td></tr><tr><td data-num=\"18\"></td><td><pre>    <span class=\"token keyword\">void</span> <span class=\"token function\">Print</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"19\"></td><td><pre>    <span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"20\"></td><td><pre>        cout <span class=\"token operator\">&lt;&lt;</span> m_year <span class=\"token operator\">&lt;&lt;</span> <span class=\"token string\">\"-\"</span> <span class=\"token operator\">&lt;&lt;</span> m_month <span class=\"token operator\">&lt;&lt;</span> <span class=\"token string\">\"-\"</span> <span class=\"token operator\">&lt;&lt;</span> m_day <span class=\"token operator\">&lt;&lt;</span> endl<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"21\"></td><td><pre>    <span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"22\"></td><td><pre></pre></td></tr><tr><td data-num=\"23\"></td><td><pre><span class=\"token keyword\">private</span><span class=\"token operator\">:</span></pre></td></tr><tr><td data-num=\"24\"></td><td><pre>    <span class=\"token keyword\">int</span> m_year<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"25\"></td><td><pre>    <span class=\"token keyword\">int</span> m_month<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"26\"></td><td><pre>    <span class=\"token keyword\">int</span> m_day<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"27\"></td><td><pre><span class=\"token punctuation\">&#125;</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"28\"></td><td><pre></pre></td></tr><tr><td data-num=\"29\"></td><td><pre><span class=\"token keyword\">int</span> <span class=\"token function\">main</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"30\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"31\"></td><td><pre>    Date d1<span class=\"token punctuation\">;</span>\t<span class=\"token comment\">// 调用无参的构造函数</span></pre></td></tr><tr><td data-num=\"32\"></td><td><pre>    Date <span class=\"token function\">d2</span><span class=\"token punctuation\">(</span><span class=\"token number\">2024</span><span class=\"token punctuation\">,</span> <span class=\"token number\">5</span><span class=\"token punctuation\">,</span> <span class=\"token number\">22</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\t<span class=\"token comment\">// 调用带参的构造函数</span></pre></td></tr><tr><td data-num=\"33\"></td><td><pre></pre></td></tr><tr><td data-num=\"34\"></td><td><pre>    <span class=\"token keyword\">return</span> <span class=\"token number\">0</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"35\"></td><td><pre><span class=\"token punctuation\">&#125;</span></pre></td></tr></table></figure><p><mark>注意：这里实例化时不能这样写：</mark></p>\n<figure class=\"highlight cpp\"><figcaption data-lang=\"C++\"></figcaption><table><tr><td data-num=\"1\"></td><td><pre><span class=\"token keyword\">int</span> <span class=\"token function\">main</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"2\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"3\"></td><td><pre>    Date <span class=\"token function\">d</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\t<span class=\"token comment\">// 调用无参的构造函数不要带括号！</span></pre></td></tr><tr><td data-num=\"4\"></td><td><pre></pre></td></tr><tr><td data-num=\"5\"></td><td><pre>    <span class=\"token keyword\">return</span> <span class=\"token number\">0</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"6\"></td><td><pre><span class=\"token punctuation\">&#125;</span></pre></td></tr></table></figure><p><mark>这里的语句可能会被认为是在声明一个叫 d 的函数，其返回值是 Date 类型的对象。</mark></p>\n</li>\n<li>\n<p>如果类中没有显式定义构造函数，编译器会自动生成一个无参的构造函数，如果显式定义了就不会这么做。</p>\n<p>这里默认生成的构造函数是遵循什么规则给对象初始化的呢？且看：</p>\n<p>C++ 中的类型分为<strong>内置类型</strong>（基本类型，比如 int、double 这些自带的）和<strong>自定义类型</strong>（我们用 class、struct、union 等自己定义出来的）。而默认生成的构造函数<strong>不一定会对内置类型进行初始化</strong>（不排除某些编译器有自己的想法？），对于<strong>自定义类型编译器会去寻找其构造函数以实现初始化</strong>。</p>\n<p>但是在 C++11 中，打了一个补丁：<strong>内置成员变量可以在类中声明时给默认值（要给就全给）。</strong></p>\n<figure class=\"highlight cpp\"><figcaption data-lang=\"C++\"></figcaption><table><tr><td data-num=\"1\"></td><td><pre><span class=\"token keyword\">class</span> <span class=\"token class-name\">Date</span></pre></td></tr><tr><td data-num=\"2\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"3\"></td><td><pre><span class=\"token keyword\">public</span><span class=\"token operator\">:</span></pre></td></tr><tr><td data-num=\"4\"></td><td><pre>    <span class=\"token function\">Date</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">int</span> y<span class=\"token punctuation\">,</span> <span class=\"token keyword\">int</span> m<span class=\"token punctuation\">,</span> <span class=\"token keyword\">int</span> d<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"5\"></td><td><pre>    <span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"6\"></td><td><pre>        m_year <span class=\"token operator\">=</span> y<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"7\"></td><td><pre>        m_month <span class=\"token operator\">=</span> m<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"8\"></td><td><pre>        m_day <span class=\"token operator\">=</span> d<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"9\"></td><td><pre>    <span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"10\"></td><td><pre></pre></td></tr><tr><td data-num=\"11\"></td><td><pre>    <span class=\"token keyword\">void</span> <span class=\"token function\">Print</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"12\"></td><td><pre>    <span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"13\"></td><td><pre>        cout <span class=\"token operator\">&lt;&lt;</span> m_year <span class=\"token operator\">&lt;&lt;</span> <span class=\"token string\">\"-\"</span> <span class=\"token operator\">&lt;&lt;</span> m_month <span class=\"token operator\">&lt;&lt;</span> <span class=\"token string\">\"-\"</span> <span class=\"token operator\">&lt;&lt;</span> m_day <span class=\"token operator\">&lt;&lt;</span> endl<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"14\"></td><td><pre>    <span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"15\"></td><td><pre></pre></td></tr><tr><td data-num=\"16\"></td><td><pre><span class=\"token keyword\">private</span><span class=\"token operator\">:</span></pre></td></tr><tr><td data-num=\"17\"></td><td><pre>    <span class=\"token keyword\">int</span> m_year <span class=\"token operator\">=</span> <span class=\"token number\">1900</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"18\"></td><td><pre>    <span class=\"token keyword\">int</span> m_month <span class=\"token operator\">=</span> <span class=\"token number\">1</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"19\"></td><td><pre>    <span class=\"token keyword\">int</span> m_day <span class=\"token operator\">=</span> <span class=\"token number\">1</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"20\"></td><td><pre><span class=\"token punctuation\">&#125;</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"21\"></td><td><pre></pre></td></tr><tr><td data-num=\"22\"></td><td><pre><span class=\"token keyword\">int</span> <span class=\"token function\">main</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"23\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"24\"></td><td><pre>    Date d<span class=\"token punctuation\">;</span>\t<span class=\"token comment\">//1900-1-1</span></pre></td></tr><tr><td data-num=\"25\"></td><td><pre>    d<span class=\"token punctuation\">.</span><span class=\"token function\">Print</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"26\"></td><td><pre></pre></td></tr><tr><td data-num=\"27\"></td><td><pre>    <span class=\"token keyword\">return</span> <span class=\"token number\">0</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"28\"></td><td><pre><span class=\"token punctuation\">&#125;</span></pre></td></tr></table></figure></li>\n</ol>\n<h3 id=\"析构函数-destructor\"><a class=\"anchor\" href=\"#析构函数-destructor\">#</a> 析构函数 （Destructor）</h3>\n<p>析构函数与构造函数相反，<strong>在对象销毁时自动调用析构函数，完成对象中资源的清理工作</strong>。</p>\n<h4 id=\"析构函数的特点\"><a class=\"anchor\" href=\"#析构函数的特点\">#</a> 析构函数的特点</h4>\n<ol>\n<li>析构函数名是在类名前加上字符 <code>~</code> 。</li>\n<li>析构函数无参数无返回值类型，<strong>不能重载</strong>。</li>\n<li>一个类只能有一个析构函数。若显式未定义，则自动生成默认的析构函数。</li>\n<li>对象生命周期结束时，自动调用析构函数。</li>\n<li>和构造函数同样的，自动生成的析构函数不会清理内置类型的变量（本身也不需要清理），对于自定义类型的变量去寻找其析构函数并调用。</li>\n</ol>\n<p>这里我们还是以之前的 Stack 类为例：</p>\n<figure class=\"highlight cpp\"><figcaption data-lang=\"C++\"><span>Stack.h</span></figcaption><table><tr><td data-num=\"1\"></td><td><pre><span class=\"token macro property\"><span class=\"token directive-hash\">#</span><span class=\"token directive keyword\">pragma</span> <span class=\"token expression\">once</span></span></pre></td></tr><tr><td data-num=\"2\"></td><td><pre></pre></td></tr><tr><td data-num=\"3\"></td><td><pre><span class=\"token macro property\"><span class=\"token directive-hash\">#</span><span class=\"token directive keyword\">include</span> <span class=\"token string\">&lt;iostream></span></span></pre></td></tr><tr><td data-num=\"4\"></td><td><pre><span class=\"token macro property\"><span class=\"token directive-hash\">#</span><span class=\"token directive keyword\">include</span> <span class=\"token string\">&lt;string></span></span></pre></td></tr><tr><td data-num=\"5\"></td><td><pre></pre></td></tr><tr><td data-num=\"6\"></td><td><pre><span class=\"token keyword\">using</span> <span class=\"token keyword\">namespace</span> std<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"7\"></td><td><pre></pre></td></tr><tr><td data-num=\"8\"></td><td><pre><span class=\"token keyword\">typedef</span> <span class=\"token keyword\">int</span> StackDataType<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"9\"></td><td><pre></pre></td></tr><tr><td data-num=\"10\"></td><td><pre><span class=\"token keyword\">class</span> <span class=\"token class-name\">Stack</span></pre></td></tr><tr><td data-num=\"11\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"12\"></td><td><pre><span class=\"token keyword\">public</span><span class=\"token operator\">:</span></pre></td></tr><tr><td data-num=\"13\"></td><td><pre>\t<span class=\"token function\">Stack</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">int</span> size<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"14\"></td><td><pre>\t<span class=\"token operator\">~</span><span class=\"token function\">Stack</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"15\"></td><td><pre>\t<span class=\"token keyword\">void</span> <span class=\"token function\">Push</span><span class=\"token punctuation\">(</span>StackDataType data<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"16\"></td><td><pre>\tStackDataType <span class=\"token function\">Pop</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"17\"></td><td><pre>\tStackDataType <span class=\"token function\">Top</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"18\"></td><td><pre>\t<span class=\"token keyword\">bool</span> <span class=\"token function\">IsEmpty</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"19\"></td><td><pre>\t<span class=\"token keyword\">bool</span> <span class=\"token function\">IsFull</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"20\"></td><td><pre>\t<span class=\"token keyword\">int</span> <span class=\"token function\">GetSize</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"21\"></td><td><pre>\t<span class=\"token keyword\">int</span> <span class=\"token function\">GetTop</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"22\"></td><td><pre></pre></td></tr><tr><td data-num=\"23\"></td><td><pre><span class=\"token keyword\">private</span><span class=\"token operator\">:</span></pre></td></tr><tr><td data-num=\"24\"></td><td><pre>\tStackDataType<span class=\"token operator\">*</span> m_data<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"25\"></td><td><pre>\t<span class=\"token keyword\">int</span> m_size<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"26\"></td><td><pre>\t<span class=\"token keyword\">int</span> m_capacity<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"27\"></td><td><pre><span class=\"token punctuation\">&#125;</span><span class=\"token punctuation\">;</span></pre></td></tr></table></figure><figure class=\"highlight cpp\"><figcaption data-lang=\"C++\"><span>Stack.cpp</span></figcaption><table><tr><td data-num=\"1\"></td><td><pre><span class=\"token macro property\"><span class=\"token directive-hash\">#</span><span class=\"token directive keyword\">include</span> <span class=\"token string\">\"Stack.h\"</span></span></pre></td></tr><tr><td data-num=\"2\"></td><td><pre></pre></td></tr><tr><td data-num=\"3\"></td><td><pre><span class=\"token class-name\">Stack</span><span class=\"token double-colon punctuation\">::</span><span class=\"token function\">Stack</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">int</span> size <span class=\"token operator\">=</span> <span class=\"token number\">4</span><span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"4\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"5\"></td><td><pre>\tm_data <span class=\"token operator\">=</span> <span class=\"token keyword\">new</span> StackDataType<span class=\"token punctuation\">[</span>size<span class=\"token punctuation\">]</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"6\"></td><td><pre>\tm_size <span class=\"token operator\">=</span> <span class=\"token number\">0</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"7\"></td><td><pre>\tm_capacity <span class=\"token operator\">=</span> size<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"8\"></td><td><pre><span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"9\"></td><td><pre></pre></td></tr><tr><td data-num=\"10\"></td><td><pre><span class=\"token class-name\">Stack</span><span class=\"token double-colon punctuation\">::</span><span class=\"token operator\">~</span><span class=\"token function\">Stack</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"11\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"12\"></td><td><pre>\t<span class=\"token keyword\">delete</span><span class=\"token punctuation\">[</span><span class=\"token punctuation\">]</span> m_data<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"13\"></td><td><pre><span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"14\"></td><td><pre></pre></td></tr><tr><td data-num=\"15\"></td><td><pre><span class=\"token keyword\">void</span> <span class=\"token class-name\">Stack</span><span class=\"token double-colon punctuation\">::</span><span class=\"token function\">Push</span><span class=\"token punctuation\">(</span>StackDataType data<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"16\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"17\"></td><td><pre>\t<span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span><span class=\"token function\">IsFull</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"18\"></td><td><pre>\t<span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"19\"></td><td><pre>\t\tcout <span class=\"token operator\">&lt;&lt;</span> <span class=\"token string\">\"Stack is full!\"</span> <span class=\"token operator\">&lt;&lt;</span> endl<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"20\"></td><td><pre>\t\t<span class=\"token keyword\">return</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"21\"></td><td><pre>\t<span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"22\"></td><td><pre></pre></td></tr><tr><td data-num=\"23\"></td><td><pre>\tm_data<span class=\"token punctuation\">[</span>m_size<span class=\"token operator\">++</span><span class=\"token punctuation\">]</span> <span class=\"token operator\">=</span> data<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"24\"></td><td><pre><span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"25\"></td><td><pre></pre></td></tr><tr><td data-num=\"26\"></td><td><pre>StackDataType <span class=\"token class-name\">Stack</span><span class=\"token double-colon punctuation\">::</span><span class=\"token function\">Pop</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"27\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"28\"></td><td><pre>\t<span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span><span class=\"token function\">IsEmpty</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"29\"></td><td><pre>\t<span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"30\"></td><td><pre>\t\tcout <span class=\"token operator\">&lt;&lt;</span> <span class=\"token string\">\"Stack is empty!\"</span> <span class=\"token operator\">&lt;&lt;</span> endl<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"31\"></td><td><pre>\t\t<span class=\"token keyword\">return</span> <span class=\"token operator\">-</span><span class=\"token number\">1</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"32\"></td><td><pre>\t<span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"33\"></td><td><pre></pre></td></tr><tr><td data-num=\"34\"></td><td><pre>\t<span class=\"token keyword\">return</span> m_data<span class=\"token punctuation\">[</span><span class=\"token operator\">--</span>m_size<span class=\"token punctuation\">]</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"35\"></td><td><pre><span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"36\"></td><td><pre></pre></td></tr><tr><td data-num=\"37\"></td><td><pre>StackDataType <span class=\"token class-name\">Stack</span><span class=\"token double-colon punctuation\">::</span><span class=\"token function\">Top</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"38\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"39\"></td><td><pre>\t<span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span><span class=\"token function\">IsEmpty</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"40\"></td><td><pre>\t<span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"41\"></td><td><pre>\t\tcout <span class=\"token operator\">&lt;&lt;</span> <span class=\"token string\">\"Stack is empty!\"</span> <span class=\"token operator\">&lt;&lt;</span> endl<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"42\"></td><td><pre>\t\t<span class=\"token keyword\">return</span> <span class=\"token operator\">-</span><span class=\"token number\">1</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"43\"></td><td><pre>\t<span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"44\"></td><td><pre></pre></td></tr><tr><td data-num=\"45\"></td><td><pre>\t<span class=\"token keyword\">return</span> m_data<span class=\"token punctuation\">[</span>m_size <span class=\"token operator\">-</span> <span class=\"token number\">1</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"46\"></td><td><pre><span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"47\"></td><td><pre></pre></td></tr><tr><td data-num=\"48\"></td><td><pre><span class=\"token keyword\">bool</span> <span class=\"token class-name\">Stack</span><span class=\"token double-colon punctuation\">::</span><span class=\"token function\">IsEmpty</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"49\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"50\"></td><td><pre>\t<span class=\"token keyword\">return</span> m_size <span class=\"token operator\">==</span> <span class=\"token number\">0</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"51\"></td><td><pre><span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"52\"></td><td><pre></pre></td></tr><tr><td data-num=\"53\"></td><td><pre><span class=\"token keyword\">bool</span> <span class=\"token class-name\">Stack</span><span class=\"token double-colon punctuation\">::</span><span class=\"token function\">IsFull</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"54\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"55\"></td><td><pre>\t<span class=\"token keyword\">return</span> m_size <span class=\"token operator\">==</span> m_capacity<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"56\"></td><td><pre><span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"57\"></td><td><pre></pre></td></tr><tr><td data-num=\"58\"></td><td><pre><span class=\"token keyword\">int</span> <span class=\"token class-name\">Stack</span><span class=\"token double-colon punctuation\">::</span><span class=\"token function\">GetSize</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"59\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"60\"></td><td><pre>\t<span class=\"token keyword\">return</span> m_size<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"61\"></td><td><pre><span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"62\"></td><td><pre></pre></td></tr><tr><td data-num=\"63\"></td><td><pre><span class=\"token keyword\">int</span> <span class=\"token class-name\">Stack</span><span class=\"token double-colon punctuation\">::</span><span class=\"token function\">GetTop</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"64\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"65\"></td><td><pre>\t<span class=\"token keyword\">return</span> m_size <span class=\"token operator\">-</span> <span class=\"token number\">1</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"66\"></td><td><pre><span class=\"token punctuation\">&#125;</span></pre></td></tr></table></figure><h3 id=\"拷贝构造函数copy-constructor\"><a class=\"anchor\" href=\"#拷贝构造函数copy-constructor\">#</a> 拷贝构造函数（Copy Constructor）</h3>\n<p>如果我们想<strong>通过一个已有对象去创建一个新对象</strong>，就要用到拷贝构造函数。简单来说，就是我们有一个类 X 的对象 a，现在想再创建一个类 X 的对象 b 而且要和 a 完全一致。那么就直接使用拷贝构造函数，使用 a 来创建 b。</p>\n<h4 id=\"拷贝构造函数的特点\"><a class=\"anchor\" href=\"#拷贝构造函数的特点\">#</a> 拷贝构造函数的特点</h4>\n<ol>\n<li>\n<p>拷贝构造函数和默认构造函数一样都是<strong>构造函数的一个重载形式</strong>。</p>\n</li>\n<li>\n<p>拷贝构造函数的<strong>参数只有一个</strong>且为<strong>类类型对象的引用</strong>。使用传值的方式会造成无穷递归调用，会被编译器报错。</p>\n<figure class=\"highlight cpp\"><figcaption data-lang=\"C++\"></figcaption><table><tr><td data-num=\"1\"></td><td><pre><span class=\"token keyword\">class</span> <span class=\"token class-name\">Date</span></pre></td></tr><tr><td data-num=\"2\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"3\"></td><td><pre><span class=\"token keyword\">public</span><span class=\"token operator\">:</span></pre></td></tr><tr><td data-num=\"4\"></td><td><pre>    <span class=\"token function\">Date</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">int</span> y<span class=\"token punctuation\">,</span> <span class=\"token keyword\">int</span> m<span class=\"token punctuation\">,</span> <span class=\"token keyword\">int</span> d<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"5\"></td><td><pre>    <span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"6\"></td><td><pre>        m_year <span class=\"token operator\">=</span> y<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"7\"></td><td><pre>        m_month <span class=\"token operator\">=</span> m<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"8\"></td><td><pre>        m_day <span class=\"token operator\">=</span> d<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"9\"></td><td><pre>    <span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"10\"></td><td><pre>    </pre></td></tr><tr><td data-num=\"11\"></td><td><pre>    <span class=\"token function\">Date</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">const</span> Date<span class=\"token operator\">&amp;</span> d<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"12\"></td><td><pre>    <span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"13\"></td><td><pre>        m_y <span class=\"token operator\">=</span> d<span class=\"token punctuation\">.</span>m_y<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"14\"></td><td><pre>        m_m <span class=\"token operator\">=</span> d<span class=\"token punctuation\">.</span>m_m<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"15\"></td><td><pre>        m_d <span class=\"token operator\">=</span> d<span class=\"token punctuation\">.</span>m_d<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"16\"></td><td><pre>    <span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"17\"></td><td><pre></pre></td></tr><tr><td data-num=\"18\"></td><td><pre>    <span class=\"token keyword\">void</span> <span class=\"token function\">Print</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"19\"></td><td><pre>    <span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"20\"></td><td><pre>        cout <span class=\"token operator\">&lt;&lt;</span> m_year <span class=\"token operator\">&lt;&lt;</span> <span class=\"token string\">\"-\"</span> <span class=\"token operator\">&lt;&lt;</span> m_month <span class=\"token operator\">&lt;&lt;</span> <span class=\"token string\">\"-\"</span> <span class=\"token operator\">&lt;&lt;</span> m_day <span class=\"token operator\">&lt;&lt;</span> endl<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"21\"></td><td><pre>    <span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"22\"></td><td><pre></pre></td></tr><tr><td data-num=\"23\"></td><td><pre><span class=\"token keyword\">private</span><span class=\"token operator\">:</span></pre></td></tr><tr><td data-num=\"24\"></td><td><pre>    <span class=\"token keyword\">int</span> m_year <span class=\"token operator\">=</span> <span class=\"token number\">1900</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"25\"></td><td><pre>    <span class=\"token keyword\">int</span> m_month <span class=\"token operator\">=</span> <span class=\"token number\">1</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"26\"></td><td><pre>    <span class=\"token keyword\">int</span> m_day <span class=\"token operator\">=</span> <span class=\"token number\">1</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"27\"></td><td><pre><span class=\"token punctuation\">&#125;</span><span class=\"token punctuation\">;</span></pre></td></tr></table></figure><p><mark>与之类似的，我们一般传参时，能使用引用就尽量使用引用类型，可以提高程序效率。</mark></p>\n</li>\n<li>\n<p><strong>如果没有显式定义，编译器会生成默认的拷贝构造函数</strong>。但是默认的拷贝构造函数是直接将内存按字节序复制过来，属于<mark>浅拷贝（值拷贝）</mark>。但是我们很多时候是需要<mark>深拷贝</mark>的，尤其是存在资源申请时，因为这种情况下依旧直接复制内存并不能申请新的资源，不能完成我们所需的拷贝。</p>\n</li>\n</ol>\n<h3 id=\"运算符重载operator-overloading\"><a class=\"anchor\" href=\"#运算符重载operator-overloading\">#</a> 运算符重载（Operator Overloading）</h3>\n<p>运算符重载是面对对象编程的一种方法。在 C++ 中，运算符重载允许我们为类对象自定义运算符的计算方法。</p>\n<p>简单来说，我们自定义一个类，编译器是不知道这个类的加减乘除等计算是如何进行的。<mark>像加减乘除等计算，一般只能用于系统的内置类型，但我们可以通过运算符重载来规定自定义类型遇到这些运算符应该怎么处理。</mark></p>\n<p><mark>运算符重载函数的名字为：operator 后面加上需要重载的运算符符号</mark>。</p>\n<p>比方说下面就是重载了日期类的<strong>日期加天数等于新日期</strong>的计算（+= 的重载）：</p>\n<figure class=\"highlight cpp\"><figcaption data-lang=\"C++\"></figcaption><table><tr><td data-num=\"1\"></td><td><pre><span class=\"token keyword\">class</span> <span class=\"token class-name\">Date</span></pre></td></tr><tr><td data-num=\"2\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"3\"></td><td><pre><span class=\"token keyword\">public</span><span class=\"token operator\">:</span></pre></td></tr><tr><td data-num=\"4\"></td><td><pre>\t<span class=\"token function\">Date</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">int</span> year <span class=\"token operator\">=</span> <span class=\"token number\">1900</span><span class=\"token punctuation\">,</span> <span class=\"token keyword\">int</span> month <span class=\"token operator\">=</span> <span class=\"token number\">1</span><span class=\"token punctuation\">,</span> <span class=\"token keyword\">int</span> day <span class=\"token operator\">=</span> <span class=\"token number\">1</span><span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"5\"></td><td><pre>    <span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"6\"></td><td><pre>        m_year <span class=\"token operator\">=</span> year<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"7\"></td><td><pre>        m_month <span class=\"token operator\">=</span> month<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"8\"></td><td><pre>        m_day <span class=\"token operator\">=</span> day<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"9\"></td><td><pre>\t<span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"10\"></td><td><pre>    </pre></td></tr><tr><td data-num=\"11\"></td><td><pre>\t<span class=\"token function\">Date</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">const</span> Date<span class=\"token operator\">&amp;</span> date<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"12\"></td><td><pre>    <span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"13\"></td><td><pre>        m_year <span class=\"token operator\">=</span> date<span class=\"token punctuation\">.</span>m_year<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"14\"></td><td><pre>        m_month <span class=\"token operator\">=</span> date<span class=\"token punctuation\">.</span>m_month<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"15\"></td><td><pre>        m_day <span class=\"token operator\">=</span> date<span class=\"token punctuation\">.</span>m_day<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"16\"></td><td><pre>    <span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"17\"></td><td><pre>        </pre></td></tr><tr><td data-num=\"18\"></td><td><pre>\t<span class=\"token operator\">~</span><span class=\"token function\">Date</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">&#123;</span><span class=\"token punctuation\">&#125;</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"19\"></td><td><pre></pre></td></tr><tr><td data-num=\"20\"></td><td><pre>\t<span class=\"token keyword\">int</span> <span class=\"token function\">GetMonthDays</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">int</span> year<span class=\"token punctuation\">,</span> <span class=\"token keyword\">int</span> month<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"21\"></td><td><pre>    <span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"22\"></td><td><pre>        <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>month <span class=\"token operator\">==</span> <span class=\"token number\">2</span><span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"23\"></td><td><pre>        <span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"24\"></td><td><pre>            <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span><span class=\"token function\">IsLeapYear</span><span class=\"token punctuation\">(</span>year<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"25\"></td><td><pre>            <span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"26\"></td><td><pre>                <span class=\"token keyword\">return</span> <span class=\"token number\">29</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"27\"></td><td><pre>            <span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"28\"></td><td><pre>            <span class=\"token keyword\">else</span></pre></td></tr><tr><td data-num=\"29\"></td><td><pre>            <span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"30\"></td><td><pre>                <span class=\"token keyword\">return</span> <span class=\"token number\">28</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"31\"></td><td><pre>            <span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"32\"></td><td><pre>        <span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"33\"></td><td><pre>        <span class=\"token keyword\">else</span> <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>month <span class=\"token operator\">==</span> <span class=\"token number\">4</span> <span class=\"token operator\">||</span> month <span class=\"token operator\">==</span> <span class=\"token number\">6</span> <span class=\"token operator\">||</span> month <span class=\"token operator\">==</span> <span class=\"token number\">9</span> <span class=\"token operator\">||</span> month <span class=\"token operator\">==</span> <span class=\"token number\">11</span><span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"34\"></td><td><pre>        <span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"35\"></td><td><pre>            <span class=\"token keyword\">return</span> <span class=\"token number\">30</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"36\"></td><td><pre>        <span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"37\"></td><td><pre>        <span class=\"token keyword\">else</span></pre></td></tr><tr><td data-num=\"38\"></td><td><pre>        <span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"39\"></td><td><pre>            <span class=\"token keyword\">return</span> <span class=\"token number\">31</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"40\"></td><td><pre>        <span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"41\"></td><td><pre>    <span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"42\"></td><td><pre>    </pre></td></tr><tr><td data-num=\"43\"></td><td><pre>\t<span class=\"token keyword\">bool</span> <span class=\"token function\">IsLeapYear</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">int</span> year<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"44\"></td><td><pre>    <span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"45\"></td><td><pre>        <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>year <span class=\"token operator\">%</span> <span class=\"token number\">4</span> <span class=\"token operator\">==</span> <span class=\"token number\">0</span> <span class=\"token operator\">&amp;&amp;</span> year <span class=\"token operator\">%</span> <span class=\"token number\">100</span> <span class=\"token operator\">!=</span> <span class=\"token number\">0</span> <span class=\"token operator\">||</span> year <span class=\"token operator\">%</span> <span class=\"token number\">400</span> <span class=\"token operator\">==</span> <span class=\"token number\">0</span><span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"46\"></td><td><pre>        <span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"47\"></td><td><pre>            <span class=\"token keyword\">return</span> <span class=\"token boolean\">true</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"48\"></td><td><pre>        <span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"49\"></td><td><pre>        <span class=\"token keyword\">else</span></pre></td></tr><tr><td data-num=\"50\"></td><td><pre>        <span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"51\"></td><td><pre>            <span class=\"token keyword\">return</span> <span class=\"token boolean\">false</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"52\"></td><td><pre>        <span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"53\"></td><td><pre>    <span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"54\"></td><td><pre></pre></td></tr><tr><td data-num=\"55\"></td><td><pre>\tDate<span class=\"token operator\">&amp;</span> <span class=\"token keyword\">operator</span><span class=\"token operator\">+=</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">int</span> days<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"56\"></td><td><pre>    <span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"57\"></td><td><pre>        <span class=\"token keyword\">while</span> <span class=\"token punctuation\">(</span>days <span class=\"token operator\">></span> <span class=\"token number\">0</span><span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"58\"></td><td><pre>        <span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"59\"></td><td><pre>            <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>days <span class=\"token operator\">+</span> m_day <span class=\"token operator\">></span> <span class=\"token function\">GetMonthDays</span><span class=\"token punctuation\">(</span>m_year<span class=\"token punctuation\">,</span> m_month<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"60\"></td><td><pre>            <span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"61\"></td><td><pre>                days <span class=\"token operator\">-=</span> <span class=\"token function\">GetMonthDays</span><span class=\"token punctuation\">(</span>m_year<span class=\"token punctuation\">,</span> m_month<span class=\"token punctuation\">)</span> <span class=\"token operator\">-</span> m_day <span class=\"token operator\">+</span> <span class=\"token number\">1</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"62\"></td><td><pre>                m_day <span class=\"token operator\">=</span> <span class=\"token number\">1</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"63\"></td><td><pre>                <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>m_month <span class=\"token operator\">==</span> <span class=\"token number\">12</span><span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"64\"></td><td><pre>                <span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"65\"></td><td><pre>                    m_month <span class=\"token operator\">=</span> <span class=\"token number\">1</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"66\"></td><td><pre>                    m_year<span class=\"token operator\">++</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"67\"></td><td><pre>                <span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"68\"></td><td><pre>                <span class=\"token keyword\">else</span></pre></td></tr><tr><td data-num=\"69\"></td><td><pre>                <span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"70\"></td><td><pre>                    m_month<span class=\"token operator\">++</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"71\"></td><td><pre>                <span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"72\"></td><td><pre>            <span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"73\"></td><td><pre>            <span class=\"token keyword\">else</span></pre></td></tr><tr><td data-num=\"74\"></td><td><pre>            <span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"75\"></td><td><pre>                m_day <span class=\"token operator\">+=</span> days<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"76\"></td><td><pre>                days <span class=\"token operator\">=</span> <span class=\"token number\">0</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"77\"></td><td><pre>            <span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"78\"></td><td><pre>        <span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"79\"></td><td><pre>        <span class=\"token keyword\">return</span> <span class=\"token operator\">*</span><span class=\"token keyword\">this</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"80\"></td><td><pre>    <span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"81\"></td><td><pre></pre></td></tr><tr><td data-num=\"82\"></td><td><pre>\t<span class=\"token keyword\">void</span> <span class=\"token function\">Print</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"83\"></td><td><pre>    <span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"84\"></td><td><pre>        std<span class=\"token double-colon punctuation\">::</span>cout <span class=\"token operator\">&lt;&lt;</span> m_year <span class=\"token operator\">&lt;&lt;</span> <span class=\"token string\">\"-\"</span> <span class=\"token operator\">&lt;&lt;</span> m_month <span class=\"token operator\">&lt;&lt;</span> <span class=\"token string\">\"-\"</span> <span class=\"token operator\">&lt;&lt;</span> m_day <span class=\"token operator\">&lt;&lt;</span> std<span class=\"token double-colon punctuation\">::</span>endl<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"85\"></td><td><pre>    <span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"86\"></td><td><pre></pre></td></tr><tr><td data-num=\"87\"></td><td><pre><span class=\"token keyword\">private</span><span class=\"token operator\">:</span></pre></td></tr><tr><td data-num=\"88\"></td><td><pre>\t<span class=\"token keyword\">int</span> m_year<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"89\"></td><td><pre>\t<span class=\"token keyword\">int</span> m_month<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"90\"></td><td><pre>\t<span class=\"token keyword\">int</span> m_day<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"91\"></td><td><pre><span class=\"token punctuation\">&#125;</span><span class=\"token punctuation\">;</span></pre></td></tr></table></figure><p>我们也可以将运算符重载为全局函数。但是需要涉及的成员变量是公有的（这会破坏类的封装性，但是也可以通过友元来解决，后面会讲）：</p>\n<figure class=\"highlight cpp\"><figcaption data-lang=\"C++\"></figcaption><table><tr><td data-num=\"1\"></td><td><pre><span class=\"token keyword\">class</span> <span class=\"token class-name\">Date</span></pre></td></tr><tr><td data-num=\"2\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"3\"></td><td><pre><span class=\"token keyword\">public</span><span class=\"token operator\">:</span></pre></td></tr><tr><td data-num=\"4\"></td><td><pre>\t<span class=\"token function\">Date</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">int</span> year <span class=\"token operator\">=</span> <span class=\"token number\">1900</span><span class=\"token punctuation\">,</span> <span class=\"token keyword\">int</span> month <span class=\"token operator\">=</span> <span class=\"token number\">1</span><span class=\"token punctuation\">,</span> <span class=\"token keyword\">int</span> day <span class=\"token operator\">=</span> <span class=\"token number\">1</span><span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"5\"></td><td><pre>    <span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"6\"></td><td><pre>        m_year <span class=\"token operator\">=</span> year<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"7\"></td><td><pre>        m_month <span class=\"token operator\">=</span> month<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"8\"></td><td><pre>        m_day <span class=\"token operator\">=</span> day<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"9\"></td><td><pre>\t<span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"10\"></td><td><pre>    </pre></td></tr><tr><td data-num=\"11\"></td><td><pre>\t<span class=\"token function\">Date</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">const</span> Date<span class=\"token operator\">&amp;</span> date<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"12\"></td><td><pre>    <span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"13\"></td><td><pre>        m_year <span class=\"token operator\">=</span> date<span class=\"token punctuation\">.</span>m_year<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"14\"></td><td><pre>        m_month <span class=\"token operator\">=</span> date<span class=\"token punctuation\">.</span>m_month<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"15\"></td><td><pre>        m_day <span class=\"token operator\">=</span> date<span class=\"token punctuation\">.</span>m_day<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"16\"></td><td><pre>    <span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"17\"></td><td><pre>        </pre></td></tr><tr><td data-num=\"18\"></td><td><pre>\t<span class=\"token operator\">~</span><span class=\"token function\">Date</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">&#123;</span><span class=\"token punctuation\">&#125;</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"19\"></td><td><pre></pre></td></tr><tr><td data-num=\"20\"></td><td><pre>\t<span class=\"token keyword\">int</span> m_year<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"21\"></td><td><pre>\t<span class=\"token keyword\">int</span> m_month<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"22\"></td><td><pre>\t<span class=\"token keyword\">int</span> m_day<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"23\"></td><td><pre><span class=\"token punctuation\">&#125;</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"24\"></td><td><pre></pre></td></tr><tr><td data-num=\"25\"></td><td><pre><span class=\"token keyword\">bool</span> <span class=\"token keyword\">operator</span><span class=\"token operator\">==</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">const</span> Date<span class=\"token operator\">&amp;</span> d1<span class=\"token punctuation\">,</span> <span class=\"token keyword\">const</span> Date<span class=\"token operator\">&amp;</span> d2<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"26\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"27\"></td><td><pre>    <span class=\"token keyword\">return</span> d1<span class=\"token punctuation\">.</span>m_year <span class=\"token operator\">==</span> d2<span class=\"token punctuation\">.</span>m_year</pre></td></tr><tr><td data-num=\"28\"></td><td><pre>        <span class=\"token operator\">&amp;&amp;</span> d1<span class=\"token punctuation\">.</span>m_month <span class=\"token operator\">==</span> d2<span class=\"token punctuation\">.</span>m_month</pre></td></tr><tr><td data-num=\"29\"></td><td><pre>        <span class=\"token operator\">&amp;&amp;</span> d1<span class=\"token punctuation\">.</span>m_day <span class=\"token operator\">==</span> d2<span class=\"token punctuation\">.</span>m_day<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"30\"></td><td><pre><span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"31\"></td><td><pre></pre></td></tr><tr><td data-num=\"32\"></td><td><pre><span class=\"token keyword\">void</span> <span class=\"token function\">test</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"33\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"34\"></td><td><pre>    Date <span class=\"token function\">d1</span><span class=\"token punctuation\">(</span><span class=\"token number\">2024</span><span class=\"token punctuation\">,</span> <span class=\"token number\">1</span><span class=\"token punctuation\">,</span> <span class=\"token number\">1</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"35\"></td><td><pre>    Date <span class=\"token function\">d2</span><span class=\"token punctuation\">(</span><span class=\"token number\">2024</span><span class=\"token punctuation\">,</span> <span class=\"token number\">1</span><span class=\"token punctuation\">,</span> <span class=\"token number\">1</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"36\"></td><td><pre>    cout <span class=\"token operator\">&lt;&lt;</span> <span class=\"token punctuation\">(</span>d1 <span class=\"token operator\">==</span> d2<span class=\"token punctuation\">)</span> <span class=\"token operator\">&lt;&lt;</span> endl<span class=\"token punctuation\">;</span>\t<span class=\"token comment\">// 由于优先级问题需要加括号</span></pre></td></tr><tr><td data-num=\"37\"></td><td><pre><span class=\"token punctuation\">&#125;</span></pre></td></tr></table></figure><p>注意：</p>\n<ol>\n<li><mark>只能重载已有的运算符，不能自创新的符号</mark>。</li>\n<li>不能对内置类型去重载。</li>\n<li>有<mark> 5 个运算符不能重载</mark>： <code>.*</code> <strong>（通过成员函数指针访问类的成员函数的运算符）</strong>、 <code>::</code> <strong>（作用域限定符）</strong>、 <code>sizeof</code> 、 <code>?:</code> <strong>（三目运算符）</strong>、 <code>.</code></li>\n<li>重载操作符<mark>至少要有一个类类型参数</mark>。<strong>作为类成员函数重载时，其有一个</strong><mark>隐藏的参数</mark><strong>，为其第一个参数 this。</strong></li>\n</ol>\n<h4 id=\"赋值运算符重载\"><a class=\"anchor\" href=\"#赋值运算符重载\">#</a> 赋值运算符重载</h4>\n<p>赋值运算符重载与拷贝构造函数类似。其参数应当选择<mark>传引用返引用</mark>以提高效率，并且这样能够支持连续赋值。</p>\n<p><strong>注意：</strong></p>\n<ol>\n<li>应当<mark>注意是否出现自己给自己赋值的情况</mark>。</li>\n<li>赋值运算符<strong>不能重载为全局函数，只能是成员函数</strong>（全局函数没有 this 指针，而且赋值运算符如果不显式实现，编译器会生成一个默认的，此时用户再在类外自己实现一个全局的赋值运算符重载，就和编译器在类中生成的默认赋值运算符重载冲突）。</li>\n<li>用户没有显式实现时，编译器会生成一个默认赋值运算符重载，以值的方式在内存逐字节拷贝（浅拷贝）。</li>\n</ol>\n<p>我们还是以日期类为例：</p>\n<figure class=\"highlight cpp\"><figcaption data-lang=\"C++\"></figcaption><table><tr><td data-num=\"1\"></td><td><pre>Date<span class=\"token operator\">&amp;</span> Date<span class=\"token double-colon punctuation\">::</span><span class=\"token keyword\">operator</span><span class=\"token operator\">=</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">const</span> Date<span class=\"token operator\">&amp;</span> date<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"2\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"3\"></td><td><pre>\t<span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span><span class=\"token keyword\">this</span> <span class=\"token operator\">!=</span> <span class=\"token operator\">&amp;</span>date<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"4\"></td><td><pre>\t<span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"5\"></td><td><pre>\t\tm_year <span class=\"token operator\">=</span> date<span class=\"token punctuation\">.</span>m_year<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"6\"></td><td><pre>\t\tm_month <span class=\"token operator\">=</span> date<span class=\"token punctuation\">.</span>m_month<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"7\"></td><td><pre>\t\tm_day <span class=\"token operator\">=</span> date<span class=\"token punctuation\">.</span>m_day<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"8\"></td><td><pre>\t<span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"9\"></td><td><pre>\t<span class=\"token keyword\">return</span> <span class=\"token operator\">*</span><span class=\"token keyword\">this</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"10\"></td><td><pre><span class=\"token punctuation\">&#125;</span></pre></td></tr></table></figure><h4 id=\"前置后置的自增和自减运算符重载\"><a class=\"anchor\" href=\"#前置后置的自增和自减运算符重载\">#</a> 前置 / 后置的自增和自减运算符重载</h4>\n<p>我们以自增运算符为例，前置自增应当这样重载：</p>\n<figure class=\"highlight cpp\"><figcaption data-lang=\"C++\"></figcaption><table><tr><td data-num=\"1\"></td><td><pre>Date<span class=\"token operator\">&amp;</span> Date<span class=\"token double-colon punctuation\">::</span><span class=\"token keyword\">operator</span><span class=\"token operator\">++</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"2\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"3\"></td><td><pre>\t<span class=\"token operator\">*</span><span class=\"token keyword\">this</span> <span class=\"token operator\">+=</span> <span class=\"token number\">1</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"4\"></td><td><pre>\t<span class=\"token keyword\">return</span> <span class=\"token operator\">*</span><span class=\"token keyword\">this</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"5\"></td><td><pre><span class=\"token punctuation\">&#125;</span></pre></td></tr></table></figure><p>而后置自增运算符应当如何重载呢？C++ 规定：<strong>为了区分，后置运算符重载时增加一个</strong> <code>int</code> <strong> 类型参数，但是调用该函数时忽略该参数，就像这样：</strong></p>\n<figure class=\"highlight cpp\"><figcaption data-lang=\"C++\"></figcaption><table><tr><td data-num=\"1\"></td><td><pre>Date Date<span class=\"token double-colon punctuation\">::</span><span class=\"token keyword\">operator</span><span class=\"token operator\">++</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">int</span><span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"2\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"3\"></td><td><pre>\tDate date <span class=\"token operator\">=</span> <span class=\"token operator\">*</span><span class=\"token keyword\">this</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"4\"></td><td><pre>\t<span class=\"token operator\">*</span><span class=\"token keyword\">this</span> <span class=\"token operator\">+=</span> <span class=\"token number\">1</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"5\"></td><td><pre>\t<span class=\"token keyword\">return</span> date<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"6\"></td><td><pre><span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"7\"></td><td><pre></pre></td></tr><tr><td data-num=\"8\"></td><td><pre><span class=\"token keyword\">void</span> <span class=\"token function\">test</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"9\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"10\"></td><td><pre>    Date d1<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"11\"></td><td><pre>    Date <span class=\"token function\">d2</span><span class=\"token punctuation\">(</span><span class=\"token number\">2024</span><span class=\"token punctuation\">,</span> <span class=\"token number\">1</span><span class=\"token punctuation\">,</span> <span class=\"token number\">1</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"12\"></td><td><pre>    d1 <span class=\"token operator\">=</span> d2<span class=\"token operator\">++</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"13\"></td><td><pre>    d1 <span class=\"token operator\">=</span> <span class=\"token operator\">++</span>d2<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"14\"></td><td><pre><span class=\"token punctuation\">&#125;</span></pre></td></tr></table></figure><p><strong>注意后置自增是使用后再自增，因此要返回自增前的旧值。</strong></p>\n<h3 id=\"const成员\"><a class=\"anchor\" href=\"#const成员\">#</a> const 成员</h3>\n<p>在成员函数的括号后面加一个 <code>const</code> ，就将这个成员函数称为<strong> const 成员函数</strong>。这里<mark>实际修饰的是该成员函数的 this 指针，表示这个成员函数不能对类的任何成员进行修改。</mark></p>\n<p><mark>建议：只要能加 const 就加 const，避免权限放大的问题。</mark></p>\n<p>具体的例子可以看下面实现完整的日期类中。</p>\n<h3 id=\"实现完整的日期类\"><a class=\"anchor\" href=\"#实现完整的日期类\">#</a> 实现完整的日期类</h3>\n<p>下面我们通过上面学的内容实现一个日期类吧！</p>\n<figure class=\"highlight cpp\"><figcaption data-lang=\"C++\"><span>Date.h</span></figcaption><table><tr><td data-num=\"1\"></td><td><pre><span class=\"token macro property\"><span class=\"token directive-hash\">#</span><span class=\"token directive keyword\">pragma</span> <span class=\"token expression\">once</span></span></pre></td></tr><tr><td data-num=\"2\"></td><td><pre></pre></td></tr><tr><td data-num=\"3\"></td><td><pre><span class=\"token keyword\">class</span> <span class=\"token class-name\">Date</span></pre></td></tr><tr><td data-num=\"4\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"5\"></td><td><pre><span class=\"token keyword\">public</span><span class=\"token operator\">:</span></pre></td></tr><tr><td data-num=\"6\"></td><td><pre>\t<span class=\"token function\">Date</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">int</span> year <span class=\"token operator\">=</span> <span class=\"token number\">1900</span><span class=\"token punctuation\">,</span> <span class=\"token keyword\">int</span> month <span class=\"token operator\">=</span> <span class=\"token number\">1</span><span class=\"token punctuation\">,</span> <span class=\"token keyword\">int</span> day <span class=\"token operator\">=</span> <span class=\"token number\">1</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"7\"></td><td><pre>\t<span class=\"token function\">Date</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">const</span> Date<span class=\"token operator\">&amp;</span> date<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"8\"></td><td><pre>\t<span class=\"token operator\">~</span><span class=\"token function\">Date</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"9\"></td><td><pre></pre></td></tr><tr><td data-num=\"10\"></td><td><pre>\t<span class=\"token keyword\">int</span> <span class=\"token function\">GetMonthDays</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">int</span> year<span class=\"token punctuation\">,</span> <span class=\"token keyword\">int</span> month<span class=\"token punctuation\">)</span> <span class=\"token keyword\">const</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"11\"></td><td><pre>\t<span class=\"token keyword\">int</span> <span class=\"token function\">GetYearDays</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">int</span> year<span class=\"token punctuation\">)</span> <span class=\"token keyword\">const</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"12\"></td><td><pre>\t<span class=\"token keyword\">bool</span> <span class=\"token function\">IsLeapYear</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">int</span> year<span class=\"token punctuation\">)</span> <span class=\"token keyword\">const</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"13\"></td><td><pre></pre></td></tr><tr><td data-num=\"14\"></td><td><pre>\tDate<span class=\"token operator\">&amp;</span> <span class=\"token keyword\">operator</span><span class=\"token operator\">+</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">int</span> days<span class=\"token punctuation\">)</span> <span class=\"token keyword\">const</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"15\"></td><td><pre>\tDate<span class=\"token operator\">&amp;</span> <span class=\"token keyword\">operator</span><span class=\"token operator\">-</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">int</span> days<span class=\"token punctuation\">)</span> <span class=\"token keyword\">const</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"16\"></td><td><pre>\tDate<span class=\"token operator\">&amp;</span> <span class=\"token keyword\">operator</span><span class=\"token operator\">-=</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">int</span> days<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"17\"></td><td><pre>\tDate<span class=\"token operator\">&amp;</span> <span class=\"token keyword\">operator</span><span class=\"token operator\">+=</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">int</span> days<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"18\"></td><td><pre>\tDate<span class=\"token operator\">&amp;</span> <span class=\"token keyword\">operator</span><span class=\"token operator\">++</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"19\"></td><td><pre>\tDate <span class=\"token keyword\">operator</span><span class=\"token operator\">++</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">int</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"20\"></td><td><pre>\tDate<span class=\"token operator\">&amp;</span> <span class=\"token keyword\">operator</span><span class=\"token operator\">--</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"21\"></td><td><pre>\tDate <span class=\"token keyword\">operator</span><span class=\"token operator\">--</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">int</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"22\"></td><td><pre>\tDate<span class=\"token operator\">&amp;</span> <span class=\"token keyword\">operator</span><span class=\"token operator\">=</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">const</span> Date<span class=\"token operator\">&amp;</span> date<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"23\"></td><td><pre>\t<span class=\"token keyword\">bool</span> <span class=\"token keyword\">operator</span><span class=\"token operator\">==</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">const</span> Date<span class=\"token operator\">&amp;</span> date<span class=\"token punctuation\">)</span> <span class=\"token keyword\">const</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"24\"></td><td><pre>\t<span class=\"token keyword\">bool</span> <span class=\"token keyword\">operator</span><span class=\"token operator\">!=</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">const</span> Date<span class=\"token operator\">&amp;</span> date<span class=\"token punctuation\">)</span> <span class=\"token keyword\">const</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"25\"></td><td><pre>\t<span class=\"token keyword\">bool</span> <span class=\"token keyword\">operator</span><span class=\"token operator\">&lt;</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">const</span> Date<span class=\"token operator\">&amp;</span> date<span class=\"token punctuation\">)</span> <span class=\"token keyword\">const</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"26\"></td><td><pre>\t<span class=\"token keyword\">bool</span> <span class=\"token keyword\">operator</span><span class=\"token operator\">></span><span class=\"token punctuation\">(</span><span class=\"token keyword\">const</span> Date<span class=\"token operator\">&amp;</span> date<span class=\"token punctuation\">)</span> <span class=\"token keyword\">const</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"27\"></td><td><pre>\t<span class=\"token keyword\">bool</span> <span class=\"token keyword\">operator</span><span class=\"token operator\">&lt;=</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">const</span> Date<span class=\"token operator\">&amp;</span> date<span class=\"token punctuation\">)</span> <span class=\"token keyword\">const</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"28\"></td><td><pre>\t<span class=\"token keyword\">bool</span> <span class=\"token keyword\">operator</span><span class=\"token operator\">>=</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">const</span> Date<span class=\"token operator\">&amp;</span> date<span class=\"token punctuation\">)</span> <span class=\"token keyword\">const</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"29\"></td><td><pre>\t<span class=\"token keyword\">int</span> <span class=\"token keyword\">operator</span><span class=\"token operator\">-</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">const</span> Date<span class=\"token operator\">&amp;</span> date<span class=\"token punctuation\">)</span> <span class=\"token keyword\">const</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"30\"></td><td><pre></pre></td></tr><tr><td data-num=\"31\"></td><td><pre>\t<span class=\"token keyword\">void</span> <span class=\"token function\">Print</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token keyword\">const</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"32\"></td><td><pre></pre></td></tr><tr><td data-num=\"33\"></td><td><pre><span class=\"token keyword\">private</span><span class=\"token operator\">:</span></pre></td></tr><tr><td data-num=\"34\"></td><td><pre>\t<span class=\"token keyword\">int</span> m_year<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"35\"></td><td><pre>\t<span class=\"token keyword\">int</span> m_month<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"36\"></td><td><pre>\t<span class=\"token keyword\">int</span> m_day<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"37\"></td><td><pre><span class=\"token punctuation\">&#125;</span><span class=\"token punctuation\">;</span></pre></td></tr></table></figure><figure class=\"highlight cpp\"><figcaption data-lang=\"C++\"><span>Date.cpp</span></figcaption><table><tr><td data-num=\"1\"></td><td><pre><span class=\"token macro property\"><span class=\"token directive-hash\">#</span><span class=\"token directive keyword\">include</span> <span class=\"token string\">&lt;iostream></span></span></pre></td></tr><tr><td data-num=\"2\"></td><td><pre><span class=\"token macro property\"><span class=\"token directive-hash\">#</span><span class=\"token directive keyword\">include</span> <span class=\"token string\">\"Date.h\"</span></span></pre></td></tr><tr><td data-num=\"3\"></td><td><pre></pre></td></tr><tr><td data-num=\"4\"></td><td><pre><span class=\"token keyword\">using</span> <span class=\"token keyword\">namespace</span> std<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"5\"></td><td><pre></pre></td></tr><tr><td data-num=\"6\"></td><td><pre><span class=\"token class-name\">Date</span><span class=\"token double-colon punctuation\">::</span><span class=\"token function\">Date</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">int</span> year<span class=\"token punctuation\">,</span> <span class=\"token keyword\">int</span> month<span class=\"token punctuation\">,</span> <span class=\"token keyword\">int</span> day<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"7\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"8\"></td><td><pre>\tm_year <span class=\"token operator\">=</span> year<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"9\"></td><td><pre>\tm_month <span class=\"token operator\">=</span> month<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"10\"></td><td><pre>\tm_day <span class=\"token operator\">=</span> day<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"11\"></td><td><pre><span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"12\"></td><td><pre></pre></td></tr><tr><td data-num=\"13\"></td><td><pre><span class=\"token class-name\">Date</span><span class=\"token double-colon punctuation\">::</span><span class=\"token function\">Date</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">const</span> Date<span class=\"token operator\">&amp;</span> date<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"14\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"15\"></td><td><pre>\tm_year <span class=\"token operator\">=</span> date<span class=\"token punctuation\">.</span>m_year<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"16\"></td><td><pre>\tm_month <span class=\"token operator\">=</span> date<span class=\"token punctuation\">.</span>m_month<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"17\"></td><td><pre>\tm_day <span class=\"token operator\">=</span> date<span class=\"token punctuation\">.</span>m_day<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"18\"></td><td><pre><span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"19\"></td><td><pre></pre></td></tr><tr><td data-num=\"20\"></td><td><pre><span class=\"token class-name\">Date</span><span class=\"token double-colon punctuation\">::</span><span class=\"token operator\">~</span><span class=\"token function\">Date</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"21\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"22\"></td><td><pre><span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"23\"></td><td><pre></pre></td></tr><tr><td data-num=\"24\"></td><td><pre><span class=\"token keyword\">int</span> <span class=\"token class-name\">Date</span><span class=\"token double-colon punctuation\">::</span><span class=\"token function\">GetMonthDays</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">int</span> year<span class=\"token punctuation\">,</span> <span class=\"token keyword\">int</span> month<span class=\"token punctuation\">)</span> <span class=\"token keyword\">const</span></pre></td></tr><tr><td data-num=\"25\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"26\"></td><td><pre>\t<span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>month <span class=\"token operator\">==</span> <span class=\"token number\">2</span><span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"27\"></td><td><pre>\t<span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"28\"></td><td><pre>\t\t<span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span><span class=\"token function\">IsLeapYear</span><span class=\"token punctuation\">(</span>year<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"29\"></td><td><pre>\t\t<span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"30\"></td><td><pre>\t\t\t<span class=\"token keyword\">return</span> <span class=\"token number\">29</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"31\"></td><td><pre>\t\t<span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"32\"></td><td><pre>\t\t<span class=\"token keyword\">else</span></pre></td></tr><tr><td data-num=\"33\"></td><td><pre>\t\t<span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"34\"></td><td><pre>\t\t\t<span class=\"token keyword\">return</span> <span class=\"token number\">28</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"35\"></td><td><pre>\t\t<span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"36\"></td><td><pre>\t<span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"37\"></td><td><pre>\t<span class=\"token keyword\">else</span> <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>month <span class=\"token operator\">==</span> <span class=\"token number\">4</span> <span class=\"token operator\">||</span> month <span class=\"token operator\">==</span> <span class=\"token number\">6</span> <span class=\"token operator\">||</span> month <span class=\"token operator\">==</span> <span class=\"token number\">9</span> <span class=\"token operator\">||</span> month <span class=\"token operator\">==</span> <span class=\"token number\">11</span><span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"38\"></td><td><pre>\t<span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"39\"></td><td><pre>\t\t<span class=\"token keyword\">return</span> <span class=\"token number\">30</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"40\"></td><td><pre>\t<span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"41\"></td><td><pre>\t<span class=\"token keyword\">else</span></pre></td></tr><tr><td data-num=\"42\"></td><td><pre>\t<span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"43\"></td><td><pre>\t\t<span class=\"token keyword\">return</span> <span class=\"token number\">31</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"44\"></td><td><pre>\t<span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"45\"></td><td><pre><span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"46\"></td><td><pre></pre></td></tr><tr><td data-num=\"47\"></td><td><pre><span class=\"token keyword\">int</span> <span class=\"token class-name\">Date</span><span class=\"token double-colon punctuation\">::</span><span class=\"token function\">GetYearDays</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">int</span> year<span class=\"token punctuation\">)</span> <span class=\"token keyword\">const</span></pre></td></tr><tr><td data-num=\"48\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"49\"></td><td><pre>\t<span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span><span class=\"token function\">IsLeapYear</span><span class=\"token punctuation\">(</span>year<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"50\"></td><td><pre>\t<span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"51\"></td><td><pre>\t\t<span class=\"token keyword\">return</span> <span class=\"token number\">366</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"52\"></td><td><pre>\t<span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"53\"></td><td><pre>\t<span class=\"token keyword\">else</span></pre></td></tr><tr><td data-num=\"54\"></td><td><pre>\t<span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"55\"></td><td><pre>\t\t<span class=\"token keyword\">return</span> <span class=\"token number\">365</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"56\"></td><td><pre>\t<span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"57\"></td><td><pre><span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"58\"></td><td><pre></pre></td></tr><tr><td data-num=\"59\"></td><td><pre><span class=\"token keyword\">bool</span> <span class=\"token class-name\">Date</span><span class=\"token double-colon punctuation\">::</span><span class=\"token function\">IsLeapYear</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">int</span> year<span class=\"token punctuation\">)</span> <span class=\"token keyword\">const</span></pre></td></tr><tr><td data-num=\"60\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"61\"></td><td><pre>\t<span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>year <span class=\"token operator\">%</span> <span class=\"token number\">4</span> <span class=\"token operator\">==</span> <span class=\"token number\">0</span> <span class=\"token operator\">&amp;&amp;</span> year <span class=\"token operator\">%</span> <span class=\"token number\">100</span> <span class=\"token operator\">!=</span> <span class=\"token number\">0</span> <span class=\"token operator\">||</span> year <span class=\"token operator\">%</span> <span class=\"token number\">400</span> <span class=\"token operator\">==</span> <span class=\"token number\">0</span><span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"62\"></td><td><pre>\t<span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"63\"></td><td><pre>\t\t<span class=\"token keyword\">return</span> <span class=\"token boolean\">true</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"64\"></td><td><pre>\t<span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"65\"></td><td><pre>\t<span class=\"token keyword\">else</span></pre></td></tr><tr><td data-num=\"66\"></td><td><pre>\t<span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"67\"></td><td><pre>\t\t<span class=\"token keyword\">return</span> <span class=\"token boolean\">false</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"68\"></td><td><pre>\t<span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"69\"></td><td><pre><span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"70\"></td><td><pre></pre></td></tr><tr><td data-num=\"71\"></td><td><pre>Date<span class=\"token operator\">&amp;</span> Date<span class=\"token double-colon punctuation\">::</span><span class=\"token keyword\">operator</span><span class=\"token operator\">+</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">int</span> days<span class=\"token punctuation\">)</span> <span class=\"token keyword\">const</span></pre></td></tr><tr><td data-num=\"72\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"73\"></td><td><pre>\tDate date <span class=\"token operator\">=</span> <span class=\"token operator\">*</span><span class=\"token keyword\">this</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"74\"></td><td><pre>\tdate <span class=\"token operator\">+=</span> days<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"75\"></td><td><pre>\t<span class=\"token keyword\">return</span> date<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"76\"></td><td><pre><span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"77\"></td><td><pre></pre></td></tr><tr><td data-num=\"78\"></td><td><pre>Date<span class=\"token operator\">&amp;</span> Date<span class=\"token double-colon punctuation\">::</span><span class=\"token keyword\">operator</span><span class=\"token operator\">-</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">int</span> days<span class=\"token punctuation\">)</span> <span class=\"token keyword\">const</span></pre></td></tr><tr><td data-num=\"79\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"80\"></td><td><pre>\tDate date <span class=\"token operator\">=</span> <span class=\"token operator\">*</span><span class=\"token keyword\">this</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"81\"></td><td><pre>\tdate <span class=\"token operator\">-=</span> days<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"82\"></td><td><pre>\t<span class=\"token keyword\">return</span> date<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"83\"></td><td><pre><span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"84\"></td><td><pre></pre></td></tr><tr><td data-num=\"85\"></td><td><pre>Date<span class=\"token operator\">&amp;</span> Date<span class=\"token double-colon punctuation\">::</span><span class=\"token keyword\">operator</span><span class=\"token operator\">-=</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">int</span> days<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"86\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"87\"></td><td><pre>\t<span class=\"token keyword\">while</span> <span class=\"token punctuation\">(</span>days <span class=\"token operator\">></span> <span class=\"token number\">0</span><span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"88\"></td><td><pre>\t<span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"89\"></td><td><pre>\t\t<span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>days <span class=\"token operator\">>=</span> m_day<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"90\"></td><td><pre>\t\t<span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"91\"></td><td><pre>\t\t\tdays <span class=\"token operator\">-=</span> m_day<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"92\"></td><td><pre>\t\t\t<span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>m_month <span class=\"token operator\">==</span> <span class=\"token number\">1</span><span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"93\"></td><td><pre>\t\t\t<span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"94\"></td><td><pre>\t\t\t\tm_month <span class=\"token operator\">=</span> <span class=\"token number\">12</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"95\"></td><td><pre>\t\t\t\tm_year<span class=\"token operator\">--</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"96\"></td><td><pre>\t\t\t<span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"97\"></td><td><pre>\t\t\t<span class=\"token keyword\">else</span></pre></td></tr><tr><td data-num=\"98\"></td><td><pre>\t\t\t<span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"99\"></td><td><pre>\t\t\t\tm_month<span class=\"token operator\">--</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"100\"></td><td><pre>\t\t\t<span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"101\"></td><td><pre>\t\t\tm_day <span class=\"token operator\">=</span> <span class=\"token function\">GetMonthDays</span><span class=\"token punctuation\">(</span>m_year<span class=\"token punctuation\">,</span> m_month<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"102\"></td><td><pre>\t\t<span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"103\"></td><td><pre>\t\t<span class=\"token keyword\">else</span></pre></td></tr><tr><td data-num=\"104\"></td><td><pre>\t\t<span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"105\"></td><td><pre>\t\t\tm_day <span class=\"token operator\">-=</span> days<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"106\"></td><td><pre>\t\t\tdays <span class=\"token operator\">=</span> <span class=\"token number\">0</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"107\"></td><td><pre>\t\t<span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"108\"></td><td><pre>\t<span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"109\"></td><td><pre>\t<span class=\"token keyword\">return</span> <span class=\"token operator\">*</span><span class=\"token keyword\">this</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"110\"></td><td><pre><span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"111\"></td><td><pre></pre></td></tr><tr><td data-num=\"112\"></td><td><pre>Date<span class=\"token operator\">&amp;</span> Date<span class=\"token double-colon punctuation\">::</span><span class=\"token keyword\">operator</span><span class=\"token operator\">+=</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">int</span> days<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"113\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"114\"></td><td><pre>\t<span class=\"token keyword\">while</span> <span class=\"token punctuation\">(</span>days <span class=\"token operator\">></span> <span class=\"token number\">0</span><span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"115\"></td><td><pre>\t<span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"116\"></td><td><pre>\t\t<span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>days <span class=\"token operator\">+</span> m_day <span class=\"token operator\">></span> <span class=\"token function\">GetMonthDays</span><span class=\"token punctuation\">(</span>m_year<span class=\"token punctuation\">,</span> m_month<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"117\"></td><td><pre>\t\t<span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"118\"></td><td><pre>\t\t\tdays <span class=\"token operator\">-=</span> <span class=\"token function\">GetMonthDays</span><span class=\"token punctuation\">(</span>m_year<span class=\"token punctuation\">,</span> m_month<span class=\"token punctuation\">)</span> <span class=\"token operator\">-</span> m_day <span class=\"token operator\">+</span> <span class=\"token number\">1</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"119\"></td><td><pre>\t\t\tm_day <span class=\"token operator\">=</span> <span class=\"token number\">1</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"120\"></td><td><pre>\t\t\t<span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>m_month <span class=\"token operator\">==</span> <span class=\"token number\">12</span><span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"121\"></td><td><pre>\t\t\t<span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"122\"></td><td><pre>\t\t\t\tm_month <span class=\"token operator\">=</span> <span class=\"token number\">1</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"123\"></td><td><pre>\t\t\t\tm_year<span class=\"token operator\">++</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"124\"></td><td><pre>\t\t\t<span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"125\"></td><td><pre>\t\t\t<span class=\"token keyword\">else</span></pre></td></tr><tr><td data-num=\"126\"></td><td><pre>\t\t\t<span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"127\"></td><td><pre>\t\t\t\tm_month<span class=\"token operator\">++</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"128\"></td><td><pre>\t\t\t<span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"129\"></td><td><pre>\t\t<span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"130\"></td><td><pre>\t\t<span class=\"token keyword\">else</span></pre></td></tr><tr><td data-num=\"131\"></td><td><pre>\t\t<span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"132\"></td><td><pre>\t\t\tm_day <span class=\"token operator\">+=</span> days<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"133\"></td><td><pre>\t\t\tdays <span class=\"token operator\">=</span> <span class=\"token number\">0</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"134\"></td><td><pre>\t\t<span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"135\"></td><td><pre>\t<span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"136\"></td><td><pre>\t<span class=\"token keyword\">return</span> <span class=\"token operator\">*</span><span class=\"token keyword\">this</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"137\"></td><td><pre><span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"138\"></td><td><pre></pre></td></tr><tr><td data-num=\"139\"></td><td><pre>Date<span class=\"token operator\">&amp;</span> Date<span class=\"token double-colon punctuation\">::</span><span class=\"token keyword\">operator</span><span class=\"token operator\">++</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"140\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"141\"></td><td><pre>\t<span class=\"token operator\">*</span><span class=\"token keyword\">this</span> <span class=\"token operator\">+=</span> <span class=\"token number\">1</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"142\"></td><td><pre>\t<span class=\"token keyword\">return</span> <span class=\"token operator\">*</span><span class=\"token keyword\">this</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"143\"></td><td><pre><span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"144\"></td><td><pre></pre></td></tr><tr><td data-num=\"145\"></td><td><pre>Date Date<span class=\"token double-colon punctuation\">::</span><span class=\"token keyword\">operator</span><span class=\"token operator\">++</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">int</span><span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"146\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"147\"></td><td><pre>\tDate date <span class=\"token operator\">=</span> <span class=\"token operator\">*</span><span class=\"token keyword\">this</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"148\"></td><td><pre>\t<span class=\"token operator\">*</span><span class=\"token keyword\">this</span> <span class=\"token operator\">+=</span> <span class=\"token number\">1</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"149\"></td><td><pre>\t<span class=\"token keyword\">return</span> date<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"150\"></td><td><pre><span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"151\"></td><td><pre></pre></td></tr><tr><td data-num=\"152\"></td><td><pre>Date<span class=\"token operator\">&amp;</span> Date<span class=\"token double-colon punctuation\">::</span><span class=\"token keyword\">operator</span><span class=\"token operator\">--</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"153\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"154\"></td><td><pre>\t<span class=\"token operator\">*</span><span class=\"token keyword\">this</span> <span class=\"token operator\">-=</span> <span class=\"token number\">1</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"155\"></td><td><pre>\t<span class=\"token keyword\">return</span> <span class=\"token operator\">*</span><span class=\"token keyword\">this</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"156\"></td><td><pre><span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"157\"></td><td><pre></pre></td></tr><tr><td data-num=\"158\"></td><td><pre>Date Date<span class=\"token double-colon punctuation\">::</span><span class=\"token keyword\">operator</span><span class=\"token operator\">--</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">int</span><span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"159\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"160\"></td><td><pre>\tDate date <span class=\"token operator\">=</span> <span class=\"token operator\">*</span><span class=\"token keyword\">this</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"161\"></td><td><pre>\t<span class=\"token operator\">*</span><span class=\"token keyword\">this</span> <span class=\"token operator\">-=</span> <span class=\"token number\">1</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"162\"></td><td><pre>\t<span class=\"token keyword\">return</span> date<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"163\"></td><td><pre><span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"164\"></td><td><pre></pre></td></tr><tr><td data-num=\"165\"></td><td><pre>Date<span class=\"token operator\">&amp;</span> Date<span class=\"token double-colon punctuation\">::</span><span class=\"token keyword\">operator</span><span class=\"token operator\">=</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">const</span> Date<span class=\"token operator\">&amp;</span> date<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"166\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"167\"></td><td><pre>\t<span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span><span class=\"token keyword\">this</span> <span class=\"token operator\">!=</span> <span class=\"token operator\">&amp;</span>date<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"168\"></td><td><pre>\t<span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"169\"></td><td><pre>\t\tm_year <span class=\"token operator\">=</span> date<span class=\"token punctuation\">.</span>m_year<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"170\"></td><td><pre>\t\tm_month <span class=\"token operator\">=</span> date<span class=\"token punctuation\">.</span>m_month<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"171\"></td><td><pre>\t\tm_day <span class=\"token operator\">=</span> date<span class=\"token punctuation\">.</span>m_day<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"172\"></td><td><pre>\t<span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"173\"></td><td><pre>\t<span class=\"token keyword\">return</span> <span class=\"token operator\">*</span><span class=\"token keyword\">this</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"174\"></td><td><pre><span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"175\"></td><td><pre></pre></td></tr><tr><td data-num=\"176\"></td><td><pre><span class=\"token keyword\">bool</span> Date<span class=\"token double-colon punctuation\">::</span><span class=\"token keyword\">operator</span><span class=\"token operator\">==</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">const</span> Date<span class=\"token operator\">&amp;</span> date<span class=\"token punctuation\">)</span> <span class=\"token keyword\">const</span></pre></td></tr><tr><td data-num=\"177\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"178\"></td><td><pre>\t<span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>m_year <span class=\"token operator\">==</span> date<span class=\"token punctuation\">.</span>m_year <span class=\"token operator\">&amp;&amp;</span> m_month <span class=\"token operator\">==</span> date<span class=\"token punctuation\">.</span>m_month <span class=\"token operator\">&amp;&amp;</span> m_day <span class=\"token operator\">==</span> date<span class=\"token punctuation\">.</span>m_day<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"179\"></td><td><pre>\t<span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"180\"></td><td><pre>\t\t<span class=\"token keyword\">return</span> <span class=\"token boolean\">true</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"181\"></td><td><pre>\t<span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"182\"></td><td><pre>\t<span class=\"token keyword\">else</span></pre></td></tr><tr><td data-num=\"183\"></td><td><pre>\t<span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"184\"></td><td><pre>\t\t<span class=\"token keyword\">return</span> <span class=\"token boolean\">false</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"185\"></td><td><pre>\t<span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"186\"></td><td><pre><span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"187\"></td><td><pre></pre></td></tr><tr><td data-num=\"188\"></td><td><pre><span class=\"token keyword\">bool</span> Date<span class=\"token double-colon punctuation\">::</span><span class=\"token keyword\">operator</span><span class=\"token operator\">!=</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">const</span> Date<span class=\"token operator\">&amp;</span> date<span class=\"token punctuation\">)</span> <span class=\"token keyword\">const</span></pre></td></tr><tr><td data-num=\"189\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"190\"></td><td><pre>\t<span class=\"token keyword\">return</span> <span class=\"token operator\">!</span><span class=\"token punctuation\">(</span><span class=\"token operator\">*</span><span class=\"token keyword\">this</span> <span class=\"token operator\">==</span> date<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"191\"></td><td><pre><span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"192\"></td><td><pre></pre></td></tr><tr><td data-num=\"193\"></td><td><pre><span class=\"token keyword\">bool</span> Date<span class=\"token double-colon punctuation\">::</span><span class=\"token keyword\">operator</span><span class=\"token operator\">&lt;</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">const</span> Date<span class=\"token operator\">&amp;</span> date<span class=\"token punctuation\">)</span> <span class=\"token keyword\">const</span></pre></td></tr><tr><td data-num=\"194\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"195\"></td><td><pre>\t<span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>m_year <span class=\"token operator\">&lt;</span> date<span class=\"token punctuation\">.</span>m_year<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"196\"></td><td><pre>\t<span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"197\"></td><td><pre>\t\t<span class=\"token keyword\">return</span> <span class=\"token boolean\">true</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"198\"></td><td><pre>\t<span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"199\"></td><td><pre>\t<span class=\"token keyword\">else</span> <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>m_year <span class=\"token operator\">==</span> date<span class=\"token punctuation\">.</span>m_year<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"200\"></td><td><pre>\t<span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"201\"></td><td><pre>\t\t<span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>m_month <span class=\"token operator\">&lt;</span> date<span class=\"token punctuation\">.</span>m_month<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"202\"></td><td><pre>\t\t<span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"203\"></td><td><pre>\t\t\t<span class=\"token keyword\">return</span> <span class=\"token boolean\">true</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"204\"></td><td><pre>\t\t<span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"205\"></td><td><pre>\t\t<span class=\"token keyword\">else</span> <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>m_month <span class=\"token operator\">==</span> date<span class=\"token punctuation\">.</span>m_month<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"206\"></td><td><pre>\t\t<span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"207\"></td><td><pre>\t\t\t<span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span><span class=\"token generic-function\"><span class=\"token function\">m_day</span> <span class=\"token generic class-name\"><span class=\"token operator\">&lt;</span> date<span class=\"token punctuation\">.</span>m_day<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"208\"></td><td><pre>\t\t\t<span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"209\"></td><td><pre>\t\t\t\t<span class=\"token keyword\">return</span> <span class=\"token boolean\">true</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"210\"></td><td><pre>\t\t\t<span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"211\"></td><td><pre>\t\t<span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"212\"></td><td><pre>\t<span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"213\"></td><td><pre>\t<span class=\"token keyword\">return</span> <span class=\"token boolean\">false</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"214\"></td><td><pre><span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"215\"></td><td><pre></pre></td></tr><tr><td data-num=\"216\"></td><td><pre><span class=\"token keyword\">bool</span> Date<span class=\"token double-colon punctuation\">::</span><span class=\"token keyword\">operator</span><span class=\"token operator\">></span></span></span><span class=\"token punctuation\">(</span><span class=\"token keyword\">const</span> Date<span class=\"token operator\">&amp;</span> date<span class=\"token punctuation\">)</span> <span class=\"token keyword\">const</span></pre></td></tr><tr><td data-num=\"217\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"218\"></td><td><pre>\t<span class=\"token keyword\">return</span> <span class=\"token operator\">!</span><span class=\"token punctuation\">(</span><span class=\"token operator\">*</span><span class=\"token keyword\">this</span> <span class=\"token operator\">&lt;</span> date<span class=\"token punctuation\">)</span> <span class=\"token operator\">&amp;&amp;</span> <span class=\"token operator\">*</span><span class=\"token keyword\">this</span> <span class=\"token operator\">!=</span> date<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"219\"></td><td><pre><span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"220\"></td><td><pre></pre></td></tr><tr><td data-num=\"221\"></td><td><pre><span class=\"token keyword\">bool</span> Date<span class=\"token double-colon punctuation\">::</span><span class=\"token keyword\">operator</span><span class=\"token operator\">&lt;=</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">const</span> Date<span class=\"token operator\">&amp;</span> date<span class=\"token punctuation\">)</span> <span class=\"token keyword\">const</span></pre></td></tr><tr><td data-num=\"222\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"223\"></td><td><pre>\t<span class=\"token keyword\">return</span> <span class=\"token operator\">*</span><span class=\"token keyword\">this</span> <span class=\"token operator\">&lt;</span> date <span class=\"token operator\">||</span> <span class=\"token operator\">*</span><span class=\"token keyword\">this</span> <span class=\"token operator\">==</span> date<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"224\"></td><td><pre><span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"225\"></td><td><pre></pre></td></tr><tr><td data-num=\"226\"></td><td><pre><span class=\"token keyword\">bool</span> Date<span class=\"token double-colon punctuation\">::</span><span class=\"token keyword\">operator</span><span class=\"token operator\">>=</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">const</span> Date<span class=\"token operator\">&amp;</span> date<span class=\"token punctuation\">)</span> <span class=\"token keyword\">const</span></pre></td></tr><tr><td data-num=\"227\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"228\"></td><td><pre>\t<span class=\"token keyword\">return</span> <span class=\"token operator\">*</span><span class=\"token keyword\">this</span> <span class=\"token operator\">></span> date <span class=\"token operator\">||</span> <span class=\"token operator\">*</span><span class=\"token keyword\">this</span> <span class=\"token operator\">==</span> date<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"229\"></td><td><pre><span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"230\"></td><td><pre></pre></td></tr><tr><td data-num=\"231\"></td><td><pre><span class=\"token keyword\">int</span> Date<span class=\"token double-colon punctuation\">::</span><span class=\"token keyword\">operator</span><span class=\"token operator\">-</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">const</span> Date<span class=\"token operator\">&amp;</span> date<span class=\"token punctuation\">)</span> <span class=\"token keyword\">const</span></pre></td></tr><tr><td data-num=\"232\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"233\"></td><td><pre>\t<span class=\"token keyword\">int</span> days <span class=\"token operator\">=</span> <span class=\"token number\">0</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"234\"></td><td><pre>\tDate temp <span class=\"token operator\">=</span> <span class=\"token operator\">*</span><span class=\"token keyword\">this</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"235\"></td><td><pre>\t<span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>temp <span class=\"token operator\">&lt;</span> date<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"236\"></td><td><pre>\t<span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"237\"></td><td><pre>\t\t<span class=\"token keyword\">while</span> <span class=\"token punctuation\">(</span>temp <span class=\"token operator\">!=</span> date<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"238\"></td><td><pre>\t\t<span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"239\"></td><td><pre>\t\t\ttemp<span class=\"token operator\">++</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"240\"></td><td><pre>\t\t\tdays<span class=\"token operator\">++</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"241\"></td><td><pre>\t\t<span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"242\"></td><td><pre>\t<span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"243\"></td><td><pre>\t<span class=\"token keyword\">else</span></pre></td></tr><tr><td data-num=\"244\"></td><td><pre>\t<span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"245\"></td><td><pre>\t\t<span class=\"token keyword\">while</span> <span class=\"token punctuation\">(</span>temp <span class=\"token operator\">!=</span> date<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"246\"></td><td><pre>\t\t<span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"247\"></td><td><pre>\t\t\ttemp<span class=\"token operator\">--</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"248\"></td><td><pre>\t\t\tdays<span class=\"token operator\">++</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"249\"></td><td><pre>\t\t<span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"250\"></td><td><pre>\t<span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"251\"></td><td><pre>\t<span class=\"token keyword\">return</span> days<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"252\"></td><td><pre><span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"253\"></td><td><pre></pre></td></tr><tr><td data-num=\"254\"></td><td><pre><span class=\"token keyword\">void</span> <span class=\"token class-name\">Date</span><span class=\"token double-colon punctuation\">::</span><span class=\"token function\">Print</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token keyword\">const</span></pre></td></tr><tr><td data-num=\"255\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"256\"></td><td><pre>\tstd<span class=\"token double-colon punctuation\">::</span>cout <span class=\"token operator\">&lt;&lt;</span> m_year <span class=\"token operator\">&lt;&lt;</span> <span class=\"token string\">\"-\"</span> <span class=\"token operator\">&lt;&lt;</span> m_month <span class=\"token operator\">&lt;&lt;</span> <span class=\"token string\">\"-\"</span> <span class=\"token operator\">&lt;&lt;</span> m_day <span class=\"token operator\">&lt;&lt;</span> std<span class=\"token double-colon punctuation\">::</span>endl<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"257\"></td><td><pre><span class=\"token punctuation\">&#125;</span></pre></td></tr></table></figure><h3 id=\"关于取地址和const取地址运算符操作符\"><a class=\"anchor\" href=\"#关于取地址和const取地址运算符操作符\">#</a> 关于取地址和 const 取地址运算符（&amp; 操作符）</h3>\n<p>有人说我们自定义的类型能够直接取地址或者 const 取地址，因此这两种运算符也是被编译器默认重载了的默认成员函数。</p>\n<p>事实上这不能认为是类的默认成员函数，虽然我们自己可以去重载这两个运算符（不推荐，一般也用不上），但是空类生成的时候编译器并没有生成这样一个重载成员函数，这个操作是 C++ 内置的基础功能。只有当显式地为类重载了取地址操作符，这个操作的行为才会改变。</p>\n",
            "tags": [
                "计算机科学",
                "C++笔记",
                "C++",
                "类"
            ]
        },
        {
            "id": "https://www.starlinglin.top/computer-science/Cpp-programme-note/%E6%A4%8B%E9%B8%9FC++%E7%AC%94%E8%AE%B0%20%EF%BC%832%EF%BC%9A%E4%BB%8E%E7%BB%93%E6%9E%84%E4%BD%93%E5%88%B0%E7%B1%BB/",
            "url": "https://www.starlinglin.top/computer-science/Cpp-programme-note/%E6%A4%8B%E9%B8%9FC++%E7%AC%94%E8%AE%B0%20%EF%BC%832%EF%BC%9A%E4%BB%8E%E7%BB%93%E6%9E%84%E4%BD%93%E5%88%B0%E7%B1%BB/",
            "title": "椋鸟C++笔记#2：从结构体到类",
            "date_published": "2024-05-12T08:41:02.000Z",
            "content_html": "<div class=\"note warning\">\n<p>本系列暴死，不会更新了。</p>\n</div>\n<div class=\"note info\">\n<p>该系列为本人的学习笔记，主要由本人整理书写而成。部分内容来自教材、视频课程等，不能保证完全原创性。</p>\n</div>\n<p>萌新的学习笔记，写错了恳请斧正。</p>\n<h3 id=\"c中的结构体\"><a class=\"anchor\" href=\"#c中的结构体\">#</a> C++ 中的结构体</h3>\n<p>我们在 C 语音中学的结构体在 C++ 依旧适用，而且增加了其他的功能。</p>\n<p>在 C++ 中，结构体<mark>不仅可以用来定义变量，还可以定义函数</mark>。</p>\n<p>在这个函数内，还可以直接使用结构体中的变量。</p>\n<p>比如之前我们在数据结构中实现的栈现在可以这样全部放在结构体内部：</p>\n<figure class=\"highlight cpp\"><figcaption data-lang=\"C++\"></figcaption><table><tr><td data-num=\"1\"></td><td><pre><span class=\"token macro property\"><span class=\"token directive-hash\">#</span><span class=\"token directive keyword\">include</span> <span class=\"token string\">&lt;iostream></span></span></pre></td></tr><tr><td data-num=\"2\"></td><td><pre></pre></td></tr><tr><td data-num=\"3\"></td><td><pre><span class=\"token keyword\">using</span> <span class=\"token keyword\">namespace</span> std<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"4\"></td><td><pre></pre></td></tr><tr><td data-num=\"5\"></td><td><pre><span class=\"token keyword\">typedef</span> <span class=\"token keyword\">int</span> DataType<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"6\"></td><td><pre></pre></td></tr><tr><td data-num=\"7\"></td><td><pre><span class=\"token keyword\">struct</span> <span class=\"token class-name\">Stack</span></pre></td></tr><tr><td data-num=\"8\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"9\"></td><td><pre>\t<span class=\"token keyword\">void</span> <span class=\"token function\">Init</span><span class=\"token punctuation\">(</span>size_t capacity<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"10\"></td><td><pre>\t<span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"11\"></td><td><pre>\t\tm_arr <span class=\"token operator\">=</span> <span class=\"token punctuation\">(</span>DataType<span class=\"token operator\">*</span><span class=\"token punctuation\">)</span><span class=\"token function\">malloc</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">sizeof</span><span class=\"token punctuation\">(</span>DataType<span class=\"token punctuation\">)</span> <span class=\"token operator\">*</span> capacity<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"12\"></td><td><pre>\t\t<span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span><span class=\"token keyword\">nullptr</span> <span class=\"token operator\">==</span> m_arr<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"13\"></td><td><pre>\t\t<span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"14\"></td><td><pre>\t\t\t<span class=\"token function\">perror</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"malloc\"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"15\"></td><td><pre>\t\t\t<span class=\"token keyword\">return</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"16\"></td><td><pre>\t\t<span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"17\"></td><td><pre>\t\tm_capacity <span class=\"token operator\">=</span> capacity<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"18\"></td><td><pre>\t\tm_size <span class=\"token operator\">=</span> <span class=\"token number\">0</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"19\"></td><td><pre>\t<span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"20\"></td><td><pre></pre></td></tr><tr><td data-num=\"21\"></td><td><pre>\t<span class=\"token keyword\">void</span> <span class=\"token function\">Push</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">const</span> DataType<span class=\"token operator\">&amp;</span> data<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"22\"></td><td><pre>\t<span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"23\"></td><td><pre>\t\tm_arr<span class=\"token punctuation\">[</span>m_size<span class=\"token punctuation\">]</span> <span class=\"token operator\">=</span> data<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"24\"></td><td><pre>\t\t<span class=\"token operator\">++</span>m_size<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"25\"></td><td><pre>\t<span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"26\"></td><td><pre></pre></td></tr><tr><td data-num=\"27\"></td><td><pre>\t<span class=\"token keyword\">void</span> DataType <span class=\"token function\">Top</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"28\"></td><td><pre>\t<span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"29\"></td><td><pre>\t\t<span class=\"token keyword\">return</span> m_arr<span class=\"token punctuation\">[</span>m_size <span class=\"token operator\">-</span> <span class=\"token number\">1</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"30\"></td><td><pre>\t<span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"31\"></td><td><pre></pre></td></tr><tr><td data-num=\"32\"></td><td><pre>\t<span class=\"token keyword\">void</span> <span class=\"token function\">Destory</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"33\"></td><td><pre>\t<span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"34\"></td><td><pre>\t\t<span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span><span class=\"token keyword\">nullptr</span> <span class=\"token operator\">!=</span> m_arr<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"35\"></td><td><pre>\t\t<span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"36\"></td><td><pre>\t\t\t<span class=\"token function\">free</span><span class=\"token punctuation\">(</span>m_arr<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"37\"></td><td><pre>\t\t\tm_arr <span class=\"token operator\">=</span> <span class=\"token keyword\">nullptr</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"38\"></td><td><pre>\t\t\tm_capacity <span class=\"token operator\">=</span> <span class=\"token number\">0</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"39\"></td><td><pre>\t\t\tm_size <span class=\"token operator\">=</span> <span class=\"token number\">0</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"40\"></td><td><pre>\t\t<span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"41\"></td><td><pre>\t<span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"42\"></td><td><pre></pre></td></tr><tr><td data-num=\"43\"></td><td><pre>\tDataType<span class=\"token operator\">*</span> m_arr<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"44\"></td><td><pre>\tsize_t m_capacity<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"45\"></td><td><pre>\tsize_t m_size<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"46\"></td><td><pre><span class=\"token punctuation\">&#125;</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"47\"></td><td><pre></pre></td></tr><tr><td data-num=\"48\"></td><td><pre><span class=\"token keyword\">int</span> <span class=\"token function\">main</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"49\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"50\"></td><td><pre>\tStack stack<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"51\"></td><td><pre>\tstack<span class=\"token punctuation\">.</span><span class=\"token function\">Init</span><span class=\"token punctuation\">(</span><span class=\"token number\">10</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"52\"></td><td><pre>\tstack<span class=\"token punctuation\">.</span><span class=\"token function\">Push</span><span class=\"token punctuation\">(</span><span class=\"token number\">1</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"53\"></td><td><pre>\tstack<span class=\"token punctuation\">.</span><span class=\"token function\">Push</span><span class=\"token punctuation\">(</span><span class=\"token number\">2</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"54\"></td><td><pre>\tstack<span class=\"token punctuation\">.</span><span class=\"token function\">Push</span><span class=\"token punctuation\">(</span><span class=\"token number\">3</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"55\"></td><td><pre>\tstack<span class=\"token punctuation\">.</span><span class=\"token function\">Push</span><span class=\"token punctuation\">(</span><span class=\"token number\">4</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"56\"></td><td><pre>\t</pre></td></tr><tr><td data-num=\"57\"></td><td><pre>\tcout <span class=\"token operator\">&lt;&lt;</span> stack<span class=\"token punctuation\">.</span><span class=\"token function\">Top</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">&lt;&lt;</span> endl<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"58\"></td><td><pre></pre></td></tr><tr><td data-num=\"59\"></td><td><pre>\tstack<span class=\"token punctuation\">.</span><span class=\"token function\">Destory</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"60\"></td><td><pre></pre></td></tr><tr><td data-num=\"61\"></td><td><pre>\t<span class=\"token keyword\">return</span> <span class=\"token number\">0</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"62\"></td><td><pre><span class=\"token punctuation\">&#125;</span></pre></td></tr></table></figure><p>我们发现，这样<mark>把一类方法的所有函数和变量封装在一起</mark>的方式非常高效，便于代码调用和管理。</p>\n<p>在 C++ 中，引入了一个更加适合这样的封装调用的方式，那就是<strong>类（Class）</strong>。</p>\n<h3 id=\"类的定义\"><a class=\"anchor\" href=\"#类的定义\">#</a> 类的定义</h3>\n<figure class=\"highlight cpp\"><figcaption data-lang=\"C++\"></figcaption><table><tr><td data-num=\"1\"></td><td><pre><span class=\"token keyword\">class</span> <span class=\"token class-name\">classname</span></pre></td></tr><tr><td data-num=\"2\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"3\"></td><td><pre>    <span class=\"token comment\">// 类体，包括成员变量和成员函数</span></pre></td></tr><tr><td data-num=\"4\"></td><td><pre><span class=\"token punctuation\">&#125;</span><span class=\"token punctuation\">;</span>\t<span class=\"token comment\">// 注意这里要加分号，与结构体类似</span></pre></td></tr></table></figure><p><code>class</code>  是 C++ 的关键字，用于定义类；classname 是类的名字；花括号中是类的主体。</p>\n<p>同样的，我们可以在类体中放成员变量和成员函数，但是类中成员函数的定义可以有两种方式：</p>\n<ol>\n<li>\n<p>定义与声明都放在类中，对于一些简单的小函数直接定义在类中比较方便：</p>\n<figure class=\"highlight cpp\"><figcaption data-lang=\"C++\"></figcaption><table><tr><td data-num=\"1\"></td><td><pre><span class=\"token keyword\">class</span> <span class=\"token class-name\">Date</span></pre></td></tr><tr><td data-num=\"2\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"3\"></td><td><pre>    <span class=\"token keyword\">void</span> <span class=\"token function\">SetDate</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">int</span> y<span class=\"token punctuation\">,</span> <span class=\"token keyword\">int</span> m<span class=\"token punctuation\">,</span> <span class=\"token keyword\">int</span> d<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"4\"></td><td><pre>    <span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"5\"></td><td><pre>        m_year <span class=\"token operator\">=</span> y<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"6\"></td><td><pre>        m_month <span class=\"token operator\">=</span> m<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"7\"></td><td><pre>        m_day <span class=\"token operator\">=</span> d<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"8\"></td><td><pre>    <span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"9\"></td><td><pre>    </pre></td></tr><tr><td data-num=\"10\"></td><td><pre>    <span class=\"token keyword\">int</span> m_year<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"11\"></td><td><pre>    <span class=\"token keyword\">int</span> m_month<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"12\"></td><td><pre>    <span class=\"token keyword\">int</span> m_day<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"13\"></td><td><pre><span class=\"token punctuation\">&#125;</span></pre></td></tr></table></figure><p><strong>在这种情况下，编译器更倾向于将这样的函数作为内联函数处理。</strong></p>\n</li>\n<li>\n<p>定义放在类外，声明放在类中，这样可以让拥有较多较大函数的类看起来更直观：</p>\n<figure class=\"highlight cpp\"><figcaption data-lang=\"C++\"></figcaption><table><tr><td data-num=\"1\"></td><td><pre><span class=\"token macro property\"><span class=\"token directive-hash\">#</span><span class=\"token directive keyword\">include</span> <span class=\"token string\">&lt;iostream></span></span></pre></td></tr><tr><td data-num=\"2\"></td><td><pre></pre></td></tr><tr><td data-num=\"3\"></td><td><pre><span class=\"token keyword\">using</span> <span class=\"token keyword\">namespace</span> std<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"4\"></td><td><pre></pre></td></tr><tr><td data-num=\"5\"></td><td><pre><span class=\"token keyword\">typedef</span> <span class=\"token keyword\">int</span> DataType<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"6\"></td><td><pre></pre></td></tr><tr><td data-num=\"7\"></td><td><pre><span class=\"token keyword\">class</span> <span class=\"token class-name\">Stack</span></pre></td></tr><tr><td data-num=\"8\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"9\"></td><td><pre>\t<span class=\"token keyword\">void</span> <span class=\"token function\">Init</span><span class=\"token punctuation\">(</span>size_t capacity<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"10\"></td><td><pre>\t<span class=\"token keyword\">void</span> <span class=\"token function\">Push</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">const</span> DataType<span class=\"token operator\">&amp;</span> data<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"11\"></td><td><pre>\tDataType <span class=\"token function\">Top</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"12\"></td><td><pre>\t<span class=\"token keyword\">void</span> <span class=\"token function\">Destory</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"13\"></td><td><pre></pre></td></tr><tr><td data-num=\"14\"></td><td><pre>\tDataType<span class=\"token operator\">*</span> m_arr<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"15\"></td><td><pre>\tsize_t m_capacity<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"16\"></td><td><pre>\tsize_t m_size<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"17\"></td><td><pre><span class=\"token punctuation\">&#125;</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"18\"></td><td><pre></pre></td></tr><tr><td data-num=\"19\"></td><td><pre><span class=\"token keyword\">void</span> <span class=\"token class-name\">Stack</span><span class=\"token double-colon punctuation\">::</span><span class=\"token function\">Init</span><span class=\"token punctuation\">(</span>size_t capacity<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"20\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"21\"></td><td><pre>    m_arr <span class=\"token operator\">=</span> <span class=\"token punctuation\">(</span>DataType<span class=\"token operator\">*</span><span class=\"token punctuation\">)</span><span class=\"token function\">malloc</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">sizeof</span><span class=\"token punctuation\">(</span>DataType<span class=\"token punctuation\">)</span> <span class=\"token operator\">*</span> capacity<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"22\"></td><td><pre>    <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span><span class=\"token keyword\">nullptr</span> <span class=\"token operator\">==</span> m_arr<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"23\"></td><td><pre>    <span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"24\"></td><td><pre>        <span class=\"token function\">perror</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"malloc\"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"25\"></td><td><pre>        <span class=\"token keyword\">return</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"26\"></td><td><pre>    <span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"27\"></td><td><pre>    m_capacity <span class=\"token operator\">=</span> capacity<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"28\"></td><td><pre>    m_size <span class=\"token operator\">=</span> <span class=\"token number\">0</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"29\"></td><td><pre><span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"30\"></td><td><pre></pre></td></tr><tr><td data-num=\"31\"></td><td><pre><span class=\"token keyword\">void</span> <span class=\"token class-name\">Stack</span><span class=\"token double-colon punctuation\">::</span><span class=\"token function\">Push</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">const</span> DataType<span class=\"token operator\">&amp;</span> data<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"32\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"33\"></td><td><pre>    m_arr<span class=\"token punctuation\">[</span>m_size<span class=\"token punctuation\">]</span> <span class=\"token operator\">=</span> data<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"34\"></td><td><pre>    <span class=\"token operator\">++</span>m_size<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"35\"></td><td><pre><span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"36\"></td><td><pre></pre></td></tr><tr><td data-num=\"37\"></td><td><pre>DataType <span class=\"token class-name\">Stack</span><span class=\"token double-colon punctuation\">::</span><span class=\"token function\">Top</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"38\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"39\"></td><td><pre>    <span class=\"token keyword\">return</span> m_arr<span class=\"token punctuation\">[</span>m_size <span class=\"token operator\">-</span> <span class=\"token number\">1</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"40\"></td><td><pre><span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"41\"></td><td><pre></pre></td></tr><tr><td data-num=\"42\"></td><td><pre><span class=\"token keyword\">void</span> <span class=\"token class-name\">Stack</span><span class=\"token double-colon punctuation\">::</span><span class=\"token function\">Destory</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"43\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"44\"></td><td><pre>    <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span><span class=\"token keyword\">nullptr</span> <span class=\"token operator\">!=</span> m_arr<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"45\"></td><td><pre>    <span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"46\"></td><td><pre>        <span class=\"token function\">free</span><span class=\"token punctuation\">(</span>m_arr<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"47\"></td><td><pre>        m_arr <span class=\"token operator\">=</span> <span class=\"token keyword\">nullptr</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"48\"></td><td><pre>        m_capacity <span class=\"token operator\">=</span> <span class=\"token number\">0</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"49\"></td><td><pre>        m_size <span class=\"token operator\">=</span> <span class=\"token number\">0</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"50\"></td><td><pre>    <span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"51\"></td><td><pre><span class=\"token punctuation\">&#125;</span></pre></td></tr></table></figure><p>我们发现，这样声明与定义分离可以让类的结构变的简单明了。但是在类外再对这些函数作定义时就需要在<mark>函数名前加上类名和作用域限定符</mark>，就像上一篇中的命名空间域一样。</p>\n<p>其实，这也是一个域，叫类域。</p>\n</li>\n</ol>\n<h4 id=\"类域\"><a class=\"anchor\" href=\"#类域\">#</a> 类域</h4>\n<p>类域与局部域、全局域、命名空间域类似，一个类中的成员变量和成员函数都属于这个类域。</p>\n<h4 id=\"访问限定符\"><a class=\"anchor\" href=\"#访问限定符\">#</a> 访问限定符</h4>\n<p>在 C++ 中，类与结构体的成员是有访问权限这么一个属性的。访问权限有<strong> public（公有）</strong>、<strong>private（私有）</strong>、**protected（保护）** 三种。我们可以通过访问限定符来设定成员的访问权限：</p>\n<figure class=\"highlight cpp\"><figcaption data-lang=\"C++\"></figcaption><table><tr><td data-num=\"1\"></td><td><pre><span class=\"token macro property\"><span class=\"token directive-hash\">#</span><span class=\"token directive keyword\">include</span> <span class=\"token string\">&lt;iostream></span></span></pre></td></tr><tr><td data-num=\"2\"></td><td><pre></pre></td></tr><tr><td data-num=\"3\"></td><td><pre><span class=\"token keyword\">using</span> <span class=\"token keyword\">namespace</span> std<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"4\"></td><td><pre></pre></td></tr><tr><td data-num=\"5\"></td><td><pre><span class=\"token keyword\">typedef</span> <span class=\"token keyword\">int</span> DataType<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"6\"></td><td><pre></pre></td></tr><tr><td data-num=\"7\"></td><td><pre><span class=\"token keyword\">class</span> <span class=\"token class-name\">Stack</span></pre></td></tr><tr><td data-num=\"8\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"9\"></td><td><pre><span class=\"token keyword\">public</span><span class=\"token operator\">:</span></pre></td></tr><tr><td data-num=\"10\"></td><td><pre>\t<span class=\"token keyword\">void</span> <span class=\"token function\">Init</span><span class=\"token punctuation\">(</span>size_t capacity<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"11\"></td><td><pre>\t<span class=\"token keyword\">void</span> <span class=\"token function\">Push</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">const</span> DataType<span class=\"token operator\">&amp;</span> data<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"12\"></td><td><pre>\tDataType <span class=\"token function\">Top</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"13\"></td><td><pre>\t<span class=\"token keyword\">void</span> <span class=\"token function\">Destory</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"14\"></td><td><pre></pre></td></tr><tr><td data-num=\"15\"></td><td><pre><span class=\"token keyword\">private</span><span class=\"token operator\">:</span></pre></td></tr><tr><td data-num=\"16\"></td><td><pre>\tDataType<span class=\"token operator\">*</span> m_arr<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"17\"></td><td><pre>\tsize_t m_capacity<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"18\"></td><td><pre>\tsize_t m_size<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"19\"></td><td><pre><span class=\"token punctuation\">&#125;</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"20\"></td><td><pre></pre></td></tr><tr><td data-num=\"21\"></td><td><pre><span class=\"token keyword\">void</span> <span class=\"token class-name\">Stack</span><span class=\"token double-colon punctuation\">::</span><span class=\"token function\">Init</span><span class=\"token punctuation\">(</span>size_t capacity<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"22\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"23\"></td><td><pre>    m_arr <span class=\"token operator\">=</span> <span class=\"token punctuation\">(</span>DataType<span class=\"token operator\">*</span><span class=\"token punctuation\">)</span><span class=\"token function\">malloc</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">sizeof</span><span class=\"token punctuation\">(</span>DataType<span class=\"token punctuation\">)</span> <span class=\"token operator\">*</span> capacity<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"24\"></td><td><pre>    <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span><span class=\"token keyword\">nullptr</span> <span class=\"token operator\">==</span> m_arr<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"25\"></td><td><pre>    <span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"26\"></td><td><pre>        <span class=\"token function\">perror</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"malloc\"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"27\"></td><td><pre>        <span class=\"token keyword\">return</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"28\"></td><td><pre>    <span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"29\"></td><td><pre>    m_capacity <span class=\"token operator\">=</span> capacity<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"30\"></td><td><pre>    m_size <span class=\"token operator\">=</span> <span class=\"token number\">0</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"31\"></td><td><pre><span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"32\"></td><td><pre></pre></td></tr><tr><td data-num=\"33\"></td><td><pre><span class=\"token keyword\">void</span> <span class=\"token class-name\">Stack</span><span class=\"token double-colon punctuation\">::</span><span class=\"token function\">Push</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">const</span> DataType<span class=\"token operator\">&amp;</span> data<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"34\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"35\"></td><td><pre>    m_arr<span class=\"token punctuation\">[</span>m_size<span class=\"token punctuation\">]</span> <span class=\"token operator\">=</span> data<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"36\"></td><td><pre>    <span class=\"token operator\">++</span>m_size<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"37\"></td><td><pre><span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"38\"></td><td><pre></pre></td></tr><tr><td data-num=\"39\"></td><td><pre>DataType <span class=\"token class-name\">Stack</span><span class=\"token double-colon punctuation\">::</span><span class=\"token function\">Top</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"40\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"41\"></td><td><pre>    <span class=\"token keyword\">return</span> m_arr<span class=\"token punctuation\">[</span>m_size <span class=\"token operator\">-</span> <span class=\"token number\">1</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"42\"></td><td><pre><span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"43\"></td><td><pre></pre></td></tr><tr><td data-num=\"44\"></td><td><pre><span class=\"token keyword\">void</span> <span class=\"token class-name\">Stack</span><span class=\"token double-colon punctuation\">::</span><span class=\"token function\">Destory</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"45\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"46\"></td><td><pre>    <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span><span class=\"token keyword\">nullptr</span> <span class=\"token operator\">!=</span> m_arr<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"47\"></td><td><pre>    <span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"48\"></td><td><pre>        <span class=\"token function\">free</span><span class=\"token punctuation\">(</span>m_arr<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"49\"></td><td><pre>        m_arr <span class=\"token operator\">=</span> <span class=\"token keyword\">nullptr</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"50\"></td><td><pre>        m_capacity <span class=\"token operator\">=</span> <span class=\"token number\">0</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"51\"></td><td><pre>        m_size <span class=\"token operator\">=</span> <span class=\"token number\">0</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"52\"></td><td><pre>    <span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"53\"></td><td><pre><span class=\"token punctuation\">&#125;</span></pre></td></tr></table></figure><p>我们看到，在上面的程序中，从 <code>public:</code>  之后，一直到下一个访问限定符之前的内容都会被设置为公有访问权限，而 private 和 protected 同理。</p>\n<p>那么不同的访问权限到底意味着什么呢？</p>\n<ol>\n<li>public 修饰的成员在类外可以直接被访问。</li>\n<li>protected 和 private 修饰的成员在类外不能直接被访问（此处 protected 和 private 是类似的）。</li>\n<li>访问权限作用域从该访问限定符出现的位置开始直到下一个访问限定符出现时为止。</li>\n<li>如果后面没有访问限定符，作用域就到子即类结束。</li>\n<li><mark>如果没有加访问限定符，class 的默认访问权限为 private，struct 为 public。（因为 struct 要兼容 C）</mark></li>\n</ol>\n<h3 id=\"类的实例化\"><a class=\"anchor\" href=\"#类的实例化\">#</a> 类的实例化</h3>\n<p>用类类型创建对象的过程，称为类的实例化：</p>\n<ol>\n<li>\n<p><strong>类是对对象进行描述的</strong>，是一个<strong>模型</strong>或者<strong>图纸</strong>一样的东西，限定了类有哪些成员。与结构体相同，<mark>定义出一个类并没有分配实际的内存空间来存储它</mark>。</p>\n</li>\n<li>\n<p>一个类可以实例化出多个对象，<mark>实例化出的对象占用实际的物理空间</mark>，存储类的<mark>成员变量（不包括成员函数，原因下面说）</mark>。</p>\n<figure class=\"highlight cpp\"><figcaption data-lang=\"C++\"></figcaption><table><tr><td data-num=\"1\"></td><td><pre><span class=\"token keyword\">class</span> <span class=\"token class-name\">Date</span></pre></td></tr><tr><td data-num=\"2\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"3\"></td><td><pre><span class=\"token keyword\">public</span><span class=\"token operator\">:</span></pre></td></tr><tr><td data-num=\"4\"></td><td><pre>    <span class=\"token keyword\">void</span> <span class=\"token function\">SetDate</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">int</span> y<span class=\"token punctuation\">,</span> <span class=\"token keyword\">int</span> m<span class=\"token punctuation\">,</span> <span class=\"token keyword\">int</span> d<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"5\"></td><td><pre>    <span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"6\"></td><td><pre>        m_year <span class=\"token operator\">=</span> y<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"7\"></td><td><pre>        m_month <span class=\"token operator\">=</span> m<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"8\"></td><td><pre>        m_day <span class=\"token operator\">=</span> d<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"9\"></td><td><pre>    <span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"10\"></td><td><pre></pre></td></tr><tr><td data-num=\"11\"></td><td><pre><span class=\"token keyword\">private</span><span class=\"token operator\">:</span></pre></td></tr><tr><td data-num=\"12\"></td><td><pre>    <span class=\"token keyword\">int</span> m_year<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"13\"></td><td><pre>    <span class=\"token keyword\">int</span> m_month<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"14\"></td><td><pre>    <span class=\"token keyword\">int</span> m_day<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"15\"></td><td><pre><span class=\"token punctuation\">&#125;</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"16\"></td><td><pre></pre></td></tr><tr><td data-num=\"17\"></td><td><pre><span class=\"token keyword\">int</span> <span class=\"token function\">main</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"18\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"19\"></td><td><pre>    Date date<span class=\"token punctuation\">;</span>\t<span class=\"token comment\">// 实例化，对象 date 就是类 Date 实例化的结果</span></pre></td></tr><tr><td data-num=\"20\"></td><td><pre>    date<span class=\"token punctuation\">.</span><span class=\"token function\">SetDate</span><span class=\"token punctuation\">(</span><span class=\"token number\">2024</span><span class=\"token punctuation\">,</span> <span class=\"token number\">5</span><span class=\"token punctuation\">,</span> <span class=\"token number\">11</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"21\"></td><td><pre>    </pre></td></tr><tr><td data-num=\"22\"></td><td><pre>    <span class=\"token keyword\">return</span> <span class=\"token number\">0</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"23\"></td><td><pre><span class=\"token punctuation\">&#125;</span></pre></td></tr></table></figure></li>\n</ol>\n<h3 id=\"类对象模型\"><a class=\"anchor\" href=\"#类对象模型\">#</a> 类对象模型</h3>\n<p>我们如何计算类对象的大小？这就需要我们知道类对象是如何存储的。</p>\n<p>其实很简单，我们用 <code>sizeof</code>  试试就知道，类对象的大小只包括类的成员变量的大小（<mark>与结构体一样遵循内存对齐规则，详见 C 语言笔记 #28</mark>）</p>\n<p>那么成员函数呢？</p>\n<p><strong>成员函数放在公共代码区的一个类成员函数表中。</strong></p>\n<h3 id=\"this指针\"><a class=\"anchor\" href=\"#this指针\">#</a> this 指针</h3>\n<p>我们还是以日期类为例：</p>\n<figure class=\"highlight cpp\"><figcaption data-lang=\"C++\"></figcaption><table><tr><td data-num=\"1\"></td><td><pre><span class=\"token keyword\">class</span> <span class=\"token class-name\">Date</span></pre></td></tr><tr><td data-num=\"2\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"3\"></td><td><pre><span class=\"token keyword\">public</span><span class=\"token operator\">:</span></pre></td></tr><tr><td data-num=\"4\"></td><td><pre>    <span class=\"token keyword\">void</span> <span class=\"token function\">SetDate</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">int</span> y<span class=\"token punctuation\">,</span> <span class=\"token keyword\">int</span> m<span class=\"token punctuation\">,</span> <span class=\"token keyword\">int</span> d<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"5\"></td><td><pre>    <span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"6\"></td><td><pre>        m_year <span class=\"token operator\">=</span> y<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"7\"></td><td><pre>        m_month <span class=\"token operator\">=</span> m<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"8\"></td><td><pre>        m_day <span class=\"token operator\">=</span> d<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"9\"></td><td><pre>    <span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"10\"></td><td><pre></pre></td></tr><tr><td data-num=\"11\"></td><td><pre><span class=\"token keyword\">private</span><span class=\"token operator\">:</span></pre></td></tr><tr><td data-num=\"12\"></td><td><pre>    <span class=\"token keyword\">int</span> m_year<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"13\"></td><td><pre>    <span class=\"token keyword\">int</span> m_month<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"14\"></td><td><pre>    <span class=\"token keyword\">int</span> m_day<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"15\"></td><td><pre><span class=\"token punctuation\">&#125;</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"16\"></td><td><pre></pre></td></tr><tr><td data-num=\"17\"></td><td><pre><span class=\"token keyword\">int</span> <span class=\"token function\">main</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"18\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"19\"></td><td><pre>    Date date1<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"20\"></td><td><pre>    date1<span class=\"token punctuation\">.</span><span class=\"token function\">SetDate</span><span class=\"token punctuation\">(</span><span class=\"token number\">2024</span><span class=\"token punctuation\">,</span> <span class=\"token number\">5</span><span class=\"token punctuation\">,</span> <span class=\"token number\">11</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"21\"></td><td><pre>    </pre></td></tr><tr><td data-num=\"22\"></td><td><pre>    Date date2<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"23\"></td><td><pre>    date2<span class=\"token punctuation\">.</span><span class=\"token function\">SetDate</span><span class=\"token punctuation\">(</span><span class=\"token number\">2024</span><span class=\"token punctuation\">,</span> <span class=\"token number\">5</span><span class=\"token punctuation\">,</span> <span class=\"token number\">12</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"24\"></td><td><pre>    </pre></td></tr><tr><td data-num=\"25\"></td><td><pre>    <span class=\"token keyword\">return</span> <span class=\"token number\">0</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"26\"></td><td><pre><span class=\"token punctuation\">&#125;</span></pre></td></tr></table></figure><p>我们看到，对于 Date 类的两个对象，我们都调用了函数 SetDate。</p>\n<p>但是这个函数只有三个参数 y、m 和 d，而且上面提到类成员函数是储存在公共代码区的，所以两次调用的是同一个地址。</p>\n<p>那么 SetDate 函数是如何知到调用时应该对那一个对象进行操作的呢？为什么 <code>date1.SetDate(2024, 5, 11);</code>  不会去修改对象 date2 的成员变量呢？</p>\n<p>在 C++ 中，是通过引入 <code>this</code>  指针来解决这个问题的：</p>\n<p><strong>C++ 编译器给每个 “非静态的成员函数” 增加了一个隐藏的指针参数，让该指针指向当前对象（函数运行时调用该函数的对象），在函数体中所有 “成员变量” 的操作，都是通过该指针去访问。只不过所有的操作对用户是透明的，即用户不需要来传递，编译器自动完成。</strong></p>\n<p>所以上面函数定义中也可以这样写：</p>\n<figure class=\"highlight cpp\"><figcaption data-lang=\"C++\"></figcaption><table><tr><td data-num=\"1\"></td><td><pre><span class=\"token keyword\">void</span> <span class=\"token function\">SetDate</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">int</span> y<span class=\"token punctuation\">,</span> <span class=\"token keyword\">int</span> m<span class=\"token punctuation\">,</span> <span class=\"token keyword\">int</span> d<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"2\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"3\"></td><td><pre>    <span class=\"token keyword\">this</span><span class=\"token operator\">-></span>m_year <span class=\"token operator\">=</span> y<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"4\"></td><td><pre>    <span class=\"token keyword\">this</span><span class=\"token operator\">-></span>m_month <span class=\"token operator\">=</span> m<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"5\"></td><td><pre>    <span class=\"token keyword\">this</span><span class=\"token operator\">-></span>m_day <span class=\"token operator\">=</span> d<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"6\"></td><td><pre><span class=\"token punctuation\">&#125;</span></pre></td></tr></table></figure><h4 id=\"this指针的特性\"><a class=\"anchor\" href=\"#this指针的特性\">#</a> this 指针的特性</h4>\n<ol>\n<li>this 指针的类型： <code>类的类型* const</code> ，const 意味着在成员函数中<mark>不能给 this 指针赋值</mark>。</li>\n<li>只能在<mark>成员函数内部使用</mark>。</li>\n<li>本质上是<mark>成员函数的形参</mark>，当对象调用成员函数时将对象的地址作为实参传递给 this 实参。所以<mark>对象中不存储 this 指针</mark>。</li>\n<li>this 指针是成员函数的第一个<mark>隐含的指针形参</mark>，一般由 ecx 寄存器自动传递，<mark>不需要用户传递</mark>。</li>\n</ol>\n<h3 id=\"对比c与cstack的实现\"><a class=\"anchor\" href=\"#对比c与cstack的实现\">#</a> 对比 C 与 C++Stack 的实现</h3>\n<h4 id=\"c语言\"><a class=\"anchor\" href=\"#c语言\">#</a> C 语言</h4>\n<figure class=\"highlight c\"><figcaption data-lang=\"c\"><span>Stack.h</span></figcaption><table><tr><td data-num=\"1\"></td><td><pre><span class=\"token macro property\"><span class=\"token directive-hash\">#</span><span class=\"token directive keyword\">pragma</span> <span class=\"token expression\">once</span></span></pre></td></tr><tr><td data-num=\"2\"></td><td><pre></pre></td></tr><tr><td data-num=\"3\"></td><td><pre><span class=\"token macro property\"><span class=\"token directive-hash\">#</span><span class=\"token directive keyword\">include</span> <span class=\"token string\">&lt;stdbool.h></span></span></pre></td></tr><tr><td data-num=\"4\"></td><td><pre><span class=\"token macro property\"><span class=\"token directive-hash\">#</span><span class=\"token directive keyword\">include</span> <span class=\"token string\">&lt;stdlib.h></span></span></pre></td></tr><tr><td data-num=\"5\"></td><td><pre><span class=\"token macro property\"><span class=\"token directive-hash\">#</span><span class=\"token directive keyword\">include</span> <span class=\"token string\">&lt;string.h></span></span></pre></td></tr><tr><td data-num=\"6\"></td><td><pre><span class=\"token macro property\"><span class=\"token directive-hash\">#</span><span class=\"token directive keyword\">include</span> <span class=\"token string\">&lt;assert.h></span></span></pre></td></tr><tr><td data-num=\"7\"></td><td><pre></pre></td></tr><tr><td data-num=\"8\"></td><td><pre><span class=\"token comment\">// 数据类型</span></pre></td></tr><tr><td data-num=\"9\"></td><td><pre><span class=\"token keyword\">typedef</span> <span class=\"token keyword\">int</span> STDataType<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"10\"></td><td><pre></pre></td></tr><tr><td data-num=\"11\"></td><td><pre><span class=\"token keyword\">typedef</span> <span class=\"token keyword\">struct</span> <span class=\"token class-name\">Stack</span></pre></td></tr><tr><td data-num=\"12\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"13\"></td><td><pre>\tSTDataType<span class=\"token operator\">*</span> _data<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"14\"></td><td><pre>\t<span class=\"token keyword\">int</span> _top<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"15\"></td><td><pre>\t<span class=\"token keyword\">int</span> _capacity<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"16\"></td><td><pre><span class=\"token punctuation\">&#125;</span> Stack<span class=\"token punctuation\">,</span> <span class=\"token operator\">*</span> pStack<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"17\"></td><td><pre></pre></td></tr><tr><td data-num=\"18\"></td><td><pre><span class=\"token comment\">// 栈的初始化</span></pre></td></tr><tr><td data-num=\"19\"></td><td><pre><span class=\"token keyword\">void</span> <span class=\"token function\">InitStack</span><span class=\"token punctuation\">(</span>pStack pst<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"20\"></td><td><pre><span class=\"token comment\">// 压栈</span></pre></td></tr><tr><td data-num=\"21\"></td><td><pre><span class=\"token keyword\">void</span> <span class=\"token function\">StackPush</span><span class=\"token punctuation\">(</span>pStack pst<span class=\"token punctuation\">,</span> STDataType x<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"22\"></td><td><pre><span class=\"token comment\">// 弹栈</span></pre></td></tr><tr><td data-num=\"23\"></td><td><pre><span class=\"token keyword\">void</span> <span class=\"token function\">StackPop</span><span class=\"token punctuation\">(</span>pStack pst<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"24\"></td><td><pre><span class=\"token comment\">// 栈顶元素</span></pre></td></tr><tr><td data-num=\"25\"></td><td><pre>STDataType <span class=\"token function\">StackTop</span><span class=\"token punctuation\">(</span>pStack pst<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"26\"></td><td><pre><span class=\"token comment\">// 栈大小</span></pre></td></tr><tr><td data-num=\"27\"></td><td><pre><span class=\"token keyword\">int</span> <span class=\"token function\">StackSize</span><span class=\"token punctuation\">(</span>pStack pst<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"28\"></td><td><pre><span class=\"token comment\">// 栈判空</span></pre></td></tr><tr><td data-num=\"29\"></td><td><pre><span class=\"token keyword\">_Bool</span> <span class=\"token function\">StackEmpty</span><span class=\"token punctuation\">(</span>pStack pst<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"30\"></td><td><pre><span class=\"token comment\">// 栈销毁</span></pre></td></tr><tr><td data-num=\"31\"></td><td><pre><span class=\"token keyword\">void</span> <span class=\"token function\">StackDestory</span><span class=\"token punctuation\">(</span>pStack pst<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr></table></figure><figure class=\"highlight c\"><figcaption data-lang=\"c\"><span>Stack.c</span></figcaption><table><tr><td data-num=\"1\"></td><td><pre><span class=\"token macro property\"><span class=\"token directive-hash\">#</span><span class=\"token directive keyword\">include</span> <span class=\"token string\">\"Stack.h\"</span></span></pre></td></tr><tr><td data-num=\"2\"></td><td><pre></pre></td></tr><tr><td data-num=\"3\"></td><td><pre><span class=\"token comment\">// 栈的初始化</span></pre></td></tr><tr><td data-num=\"4\"></td><td><pre><span class=\"token keyword\">void</span> <span class=\"token function\">InitStack</span><span class=\"token punctuation\">(</span>pStack pst<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"5\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"6\"></td><td><pre>\t<span class=\"token function\">assert</span><span class=\"token punctuation\">(</span>pst<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"7\"></td><td><pre>\tpst<span class=\"token operator\">-></span>_data <span class=\"token operator\">=</span> <span class=\"token constant\">NULL</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"8\"></td><td><pre>\tpst<span class=\"token operator\">-></span>_top <span class=\"token operator\">=</span> <span class=\"token number\">0</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"9\"></td><td><pre>\tpst<span class=\"token operator\">-></span>_capacity <span class=\"token operator\">=</span> <span class=\"token number\">0</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"10\"></td><td><pre><span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"11\"></td><td><pre><span class=\"token comment\">// 容量检查扩容</span></pre></td></tr><tr><td data-num=\"12\"></td><td><pre><span class=\"token keyword\">void</span> <span class=\"token function\">StackCheck</span><span class=\"token punctuation\">(</span>pStack pst<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"13\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"14\"></td><td><pre>\t<span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>pst<span class=\"token operator\">-></span>_top <span class=\"token operator\">==</span> pst<span class=\"token operator\">-></span>_capacity<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"15\"></td><td><pre>\t<span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"16\"></td><td><pre>\t\t<span class=\"token keyword\">int</span> newCapacity <span class=\"token operator\">=</span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span>pst<span class=\"token operator\">-></span>_capacity <span class=\"token operator\">==</span> <span class=\"token number\">0</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">?</span> <span class=\"token number\">4</span> <span class=\"token operator\">:</span> <span class=\"token punctuation\">(</span><span class=\"token number\">2</span> <span class=\"token operator\">*</span> pst<span class=\"token operator\">-></span>_capacity<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"17\"></td><td><pre>\t\tSTDataType<span class=\"token operator\">*</span> temp <span class=\"token operator\">=</span> <span class=\"token punctuation\">(</span>STDataType<span class=\"token operator\">*</span><span class=\"token punctuation\">)</span><span class=\"token function\">realloc</span><span class=\"token punctuation\">(</span>pst<span class=\"token operator\">-></span>_data<span class=\"token punctuation\">,</span> newCapacity <span class=\"token operator\">*</span> <span class=\"token keyword\">sizeof</span><span class=\"token punctuation\">(</span>STDataType<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"18\"></td><td><pre>\t\t<span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>temp <span class=\"token operator\">==</span> <span class=\"token constant\">NULL</span><span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"19\"></td><td><pre>\t\t<span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"20\"></td><td><pre>\t\t\t<span class=\"token function\">perror</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"realloc\"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"21\"></td><td><pre>\t\t\t<span class=\"token function\">exit</span><span class=\"token punctuation\">(</span>EXIT_FAILURE<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"22\"></td><td><pre>\t\t<span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"23\"></td><td><pre>\t\tpst<span class=\"token operator\">-></span>_data <span class=\"token operator\">=</span> temp<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"24\"></td><td><pre>\t\tpst<span class=\"token operator\">-></span>_capacity <span class=\"token operator\">=</span> newCapacity<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"25\"></td><td><pre>\t<span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"26\"></td><td><pre><span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"27\"></td><td><pre><span class=\"token comment\">// 压栈</span></pre></td></tr><tr><td data-num=\"28\"></td><td><pre><span class=\"token keyword\">void</span> <span class=\"token function\">StackPush</span><span class=\"token punctuation\">(</span>pStack pst<span class=\"token punctuation\">,</span> STDataType x<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"29\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"30\"></td><td><pre>\t<span class=\"token function\">assert</span><span class=\"token punctuation\">(</span>pst<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"31\"></td><td><pre>\t<span class=\"token function\">StackCheck</span><span class=\"token punctuation\">(</span>pst<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span> </pre></td></tr><tr><td data-num=\"32\"></td><td><pre>\t<span class=\"token function\">memcpy</span><span class=\"token punctuation\">(</span><span class=\"token operator\">&amp;</span><span class=\"token punctuation\">(</span>pst<span class=\"token operator\">-></span>_data<span class=\"token punctuation\">[</span>pst<span class=\"token operator\">-></span>_top<span class=\"token punctuation\">]</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">,</span> <span class=\"token operator\">&amp;</span>x<span class=\"token punctuation\">,</span> <span class=\"token keyword\">sizeof</span><span class=\"token punctuation\">(</span>STDataType<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"33\"></td><td><pre>\tpst<span class=\"token operator\">-></span>_top<span class=\"token operator\">++</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"34\"></td><td><pre><span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"35\"></td><td><pre><span class=\"token comment\">// 弹栈</span></pre></td></tr><tr><td data-num=\"36\"></td><td><pre><span class=\"token keyword\">void</span> <span class=\"token function\">StackPop</span><span class=\"token punctuation\">(</span>pStack pst<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"37\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"38\"></td><td><pre>\t<span class=\"token function\">assert</span><span class=\"token punctuation\">(</span>pst<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"39\"></td><td><pre>\t<span class=\"token function\">assert</span><span class=\"token punctuation\">(</span><span class=\"token operator\">!</span><span class=\"token function\">StackEmpty</span><span class=\"token punctuation\">(</span>pst<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"40\"></td><td><pre>\tpst<span class=\"token operator\">-></span>_top<span class=\"token operator\">--</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"41\"></td><td><pre><span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"42\"></td><td><pre><span class=\"token comment\">// 栈顶元素</span></pre></td></tr><tr><td data-num=\"43\"></td><td><pre>STDataType <span class=\"token function\">StackTop</span><span class=\"token punctuation\">(</span>pStack pst<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"44\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"45\"></td><td><pre>\t<span class=\"token function\">assert</span><span class=\"token punctuation\">(</span>pst<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"46\"></td><td><pre>\t<span class=\"token keyword\">return</span> pst<span class=\"token operator\">-></span>_data<span class=\"token punctuation\">[</span>pst<span class=\"token operator\">-></span>_top <span class=\"token operator\">-</span> <span class=\"token number\">1</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"47\"></td><td><pre><span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"48\"></td><td><pre><span class=\"token comment\">// 栈大小</span></pre></td></tr><tr><td data-num=\"49\"></td><td><pre><span class=\"token keyword\">int</span> <span class=\"token function\">StackSize</span><span class=\"token punctuation\">(</span>pStack pst<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"50\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"51\"></td><td><pre>\t<span class=\"token function\">assert</span><span class=\"token punctuation\">(</span>pst<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"52\"></td><td><pre>\t<span class=\"token keyword\">return</span> pst<span class=\"token operator\">-></span>_top<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"53\"></td><td><pre><span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"54\"></td><td><pre><span class=\"token comment\">// 栈判空</span></pre></td></tr><tr><td data-num=\"55\"></td><td><pre><span class=\"token keyword\">_Bool</span> <span class=\"token function\">StackEmpty</span><span class=\"token punctuation\">(</span>pStack pst<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"56\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"57\"></td><td><pre>\t<span class=\"token function\">assert</span><span class=\"token punctuation\">(</span>pst<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"58\"></td><td><pre>\t<span class=\"token keyword\">return</span> pst<span class=\"token operator\">-></span>_top <span class=\"token operator\">==</span> <span class=\"token number\">0</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"59\"></td><td><pre><span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"60\"></td><td><pre><span class=\"token comment\">// 栈销毁</span></pre></td></tr><tr><td data-num=\"61\"></td><td><pre><span class=\"token keyword\">void</span> <span class=\"token function\">StackDestory</span><span class=\"token punctuation\">(</span>pStack pst<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"62\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"63\"></td><td><pre>\t<span class=\"token function\">assert</span><span class=\"token punctuation\">(</span>pst<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"64\"></td><td><pre>\t<span class=\"token function\">free</span><span class=\"token punctuation\">(</span>pst<span class=\"token operator\">-></span>_data<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"65\"></td><td><pre>\tpst<span class=\"token operator\">-></span>_capacity <span class=\"token operator\">=</span> <span class=\"token number\">0</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"66\"></td><td><pre>\tpst<span class=\"token operator\">-></span>_top <span class=\"token operator\">=</span> <span class=\"token number\">0</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"67\"></td><td><pre>\tpst<span class=\"token operator\">-></span>_data <span class=\"token operator\">=</span> <span class=\"token constant\">NULL</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"68\"></td><td><pre><span class=\"token punctuation\">&#125;</span></pre></td></tr></table></figure><h4 id=\"c\"><a class=\"anchor\" href=\"#c\">#</a> C++</h4>\n<p>先忽略 Stack 函数与～Stack 函数，下一篇笔记讲。</p>\n<figure class=\"highlight cpp\"><figcaption data-lang=\"C++\"><span>Stack.h</span></figcaption><table><tr><td data-num=\"1\"></td><td><pre><span class=\"token macro property\"><span class=\"token directive-hash\">#</span><span class=\"token directive keyword\">pragma</span> <span class=\"token expression\">once</span></span></pre></td></tr><tr><td data-num=\"2\"></td><td><pre></pre></td></tr><tr><td data-num=\"3\"></td><td><pre><span class=\"token macro property\"><span class=\"token directive-hash\">#</span><span class=\"token directive keyword\">include</span> <span class=\"token string\">&lt;iostream></span></span></pre></td></tr><tr><td data-num=\"4\"></td><td><pre><span class=\"token macro property\"><span class=\"token directive-hash\">#</span><span class=\"token directive keyword\">include</span> <span class=\"token string\">&lt;string></span></span></pre></td></tr><tr><td data-num=\"5\"></td><td><pre></pre></td></tr><tr><td data-num=\"6\"></td><td><pre><span class=\"token keyword\">using</span> <span class=\"token keyword\">namespace</span> std<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"7\"></td><td><pre></pre></td></tr><tr><td data-num=\"8\"></td><td><pre><span class=\"token keyword\">typedef</span> <span class=\"token keyword\">int</span> StackDataType<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"9\"></td><td><pre></pre></td></tr><tr><td data-num=\"10\"></td><td><pre><span class=\"token keyword\">class</span> <span class=\"token class-name\">Stack</span></pre></td></tr><tr><td data-num=\"11\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"12\"></td><td><pre><span class=\"token keyword\">public</span><span class=\"token operator\">:</span></pre></td></tr><tr><td data-num=\"13\"></td><td><pre>\t<span class=\"token function\">Stack</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">int</span> size<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"14\"></td><td><pre>\t<span class=\"token operator\">~</span><span class=\"token function\">Stack</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"15\"></td><td><pre>\t<span class=\"token keyword\">void</span> <span class=\"token function\">Push</span><span class=\"token punctuation\">(</span>StackDataType data<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"16\"></td><td><pre>\tStackDataType <span class=\"token function\">Pop</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"17\"></td><td><pre>\tStackDataType <span class=\"token function\">Top</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"18\"></td><td><pre>\t<span class=\"token keyword\">bool</span> <span class=\"token function\">IsEmpty</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"19\"></td><td><pre>\t<span class=\"token keyword\">bool</span> <span class=\"token function\">IsFull</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"20\"></td><td><pre>\t<span class=\"token keyword\">int</span> <span class=\"token function\">GetSize</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"21\"></td><td><pre>\t<span class=\"token keyword\">int</span> <span class=\"token function\">GetTop</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"22\"></td><td><pre></pre></td></tr><tr><td data-num=\"23\"></td><td><pre><span class=\"token keyword\">private</span><span class=\"token operator\">:</span></pre></td></tr><tr><td data-num=\"24\"></td><td><pre>\tStackDataType<span class=\"token operator\">*</span> m_data<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"25\"></td><td><pre>\t<span class=\"token keyword\">int</span> m_size<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"26\"></td><td><pre>\t<span class=\"token keyword\">int</span> m_capacity<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"27\"></td><td><pre><span class=\"token punctuation\">&#125;</span><span class=\"token punctuation\">;</span></pre></td></tr></table></figure><figure class=\"highlight cpp\"><figcaption data-lang=\"C++\"><span>Stack.cpp</span></figcaption><table><tr><td data-num=\"1\"></td><td><pre><span class=\"token macro property\"><span class=\"token directive-hash\">#</span><span class=\"token directive keyword\">include</span> <span class=\"token string\">\"Stack.h\"</span></span></pre></td></tr><tr><td data-num=\"2\"></td><td><pre></pre></td></tr><tr><td data-num=\"3\"></td><td><pre><span class=\"token class-name\">Stack</span><span class=\"token double-colon punctuation\">::</span><span class=\"token function\">Stack</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">int</span> size <span class=\"token operator\">=</span> <span class=\"token number\">4</span><span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"4\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"5\"></td><td><pre>\tm_data <span class=\"token operator\">=</span> <span class=\"token keyword\">new</span> StackDataType<span class=\"token punctuation\">[</span>size<span class=\"token punctuation\">]</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"6\"></td><td><pre>\tm_size <span class=\"token operator\">=</span> <span class=\"token number\">0</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"7\"></td><td><pre>\tm_capacity <span class=\"token operator\">=</span> size<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"8\"></td><td><pre><span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"9\"></td><td><pre></pre></td></tr><tr><td data-num=\"10\"></td><td><pre><span class=\"token class-name\">Stack</span><span class=\"token double-colon punctuation\">::</span><span class=\"token operator\">~</span><span class=\"token function\">Stack</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"11\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"12\"></td><td><pre>\t<span class=\"token keyword\">delete</span><span class=\"token punctuation\">[</span><span class=\"token punctuation\">]</span> m_data<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"13\"></td><td><pre><span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"14\"></td><td><pre></pre></td></tr><tr><td data-num=\"15\"></td><td><pre><span class=\"token keyword\">void</span> <span class=\"token class-name\">Stack</span><span class=\"token double-colon punctuation\">::</span><span class=\"token function\">Push</span><span class=\"token punctuation\">(</span>StackDataType data<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"16\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"17\"></td><td><pre>\t<span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span><span class=\"token function\">IsFull</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"18\"></td><td><pre>\t<span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"19\"></td><td><pre>\t\tcout <span class=\"token operator\">&lt;&lt;</span> <span class=\"token string\">\"Stack is full!\"</span> <span class=\"token operator\">&lt;&lt;</span> endl<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"20\"></td><td><pre>\t\t<span class=\"token keyword\">return</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"21\"></td><td><pre>\t<span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"22\"></td><td><pre></pre></td></tr><tr><td data-num=\"23\"></td><td><pre>\tm_data<span class=\"token punctuation\">[</span>m_size<span class=\"token operator\">++</span><span class=\"token punctuation\">]</span> <span class=\"token operator\">=</span> data<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"24\"></td><td><pre><span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"25\"></td><td><pre></pre></td></tr><tr><td data-num=\"26\"></td><td><pre>StackDataType <span class=\"token class-name\">Stack</span><span class=\"token double-colon punctuation\">::</span><span class=\"token function\">Pop</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"27\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"28\"></td><td><pre>\t<span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span><span class=\"token function\">IsEmpty</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"29\"></td><td><pre>\t<span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"30\"></td><td><pre>\t\tcout <span class=\"token operator\">&lt;&lt;</span> <span class=\"token string\">\"Stack is empty!\"</span> <span class=\"token operator\">&lt;&lt;</span> endl<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"31\"></td><td><pre>\t\t<span class=\"token keyword\">return</span> <span class=\"token operator\">-</span><span class=\"token number\">1</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"32\"></td><td><pre>\t<span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"33\"></td><td><pre></pre></td></tr><tr><td data-num=\"34\"></td><td><pre>\t<span class=\"token keyword\">return</span> m_data<span class=\"token punctuation\">[</span><span class=\"token operator\">--</span>m_size<span class=\"token punctuation\">]</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"35\"></td><td><pre><span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"36\"></td><td><pre></pre></td></tr><tr><td data-num=\"37\"></td><td><pre>StackDataType <span class=\"token class-name\">Stack</span><span class=\"token double-colon punctuation\">::</span><span class=\"token function\">Top</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"38\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"39\"></td><td><pre>\t<span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span><span class=\"token function\">IsEmpty</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"40\"></td><td><pre>\t<span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"41\"></td><td><pre>\t\tcout <span class=\"token operator\">&lt;&lt;</span> <span class=\"token string\">\"Stack is empty!\"</span> <span class=\"token operator\">&lt;&lt;</span> endl<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"42\"></td><td><pre>\t\t<span class=\"token keyword\">return</span> <span class=\"token operator\">-</span><span class=\"token number\">1</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"43\"></td><td><pre>\t<span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"44\"></td><td><pre></pre></td></tr><tr><td data-num=\"45\"></td><td><pre>\t<span class=\"token keyword\">return</span> m_data<span class=\"token punctuation\">[</span>m_size <span class=\"token operator\">-</span> <span class=\"token number\">1</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"46\"></td><td><pre><span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"47\"></td><td><pre></pre></td></tr><tr><td data-num=\"48\"></td><td><pre><span class=\"token keyword\">bool</span> <span class=\"token class-name\">Stack</span><span class=\"token double-colon punctuation\">::</span><span class=\"token function\">IsEmpty</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"49\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"50\"></td><td><pre>\t<span class=\"token keyword\">return</span> m_size <span class=\"token operator\">==</span> <span class=\"token number\">0</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"51\"></td><td><pre><span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"52\"></td><td><pre></pre></td></tr><tr><td data-num=\"53\"></td><td><pre><span class=\"token keyword\">bool</span> <span class=\"token class-name\">Stack</span><span class=\"token double-colon punctuation\">::</span><span class=\"token function\">IsFull</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"54\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"55\"></td><td><pre>\t<span class=\"token keyword\">return</span> m_size <span class=\"token operator\">==</span> m_capacity<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"56\"></td><td><pre><span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"57\"></td><td><pre></pre></td></tr><tr><td data-num=\"58\"></td><td><pre><span class=\"token keyword\">int</span> <span class=\"token class-name\">Stack</span><span class=\"token double-colon punctuation\">::</span><span class=\"token function\">GetSize</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"59\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"60\"></td><td><pre>\t<span class=\"token keyword\">return</span> m_size<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"61\"></td><td><pre><span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"62\"></td><td><pre></pre></td></tr><tr><td data-num=\"63\"></td><td><pre><span class=\"token keyword\">int</span> <span class=\"token class-name\">Stack</span><span class=\"token double-colon punctuation\">::</span><span class=\"token function\">GetTop</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"64\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"65\"></td><td><pre>\t<span class=\"token keyword\">return</span> m_size <span class=\"token operator\">-</span> <span class=\"token number\">1</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"66\"></td><td><pre><span class=\"token punctuation\">&#125;</span></pre></td></tr></table></figure>",
            "tags": [
                "计算机科学",
                "C++笔记",
                "C++",
                "类"
            ]
        },
        {
            "id": "https://www.starlinglin.top/computer-science/Cpp-programme-note/%E6%A4%8B%E9%B8%9FC++%E7%AC%94%E8%AE%B0%20%EF%BC%831%EF%BC%9AC++%E5%88%9D%E8%AF%86/",
            "url": "https://www.starlinglin.top/computer-science/Cpp-programme-note/%E6%A4%8B%E9%B8%9FC++%E7%AC%94%E8%AE%B0%20%EF%BC%831%EF%BC%9AC++%E5%88%9D%E8%AF%86/",
            "title": "椋鸟C++笔记#1：C++初识",
            "date_published": "2024-04-28T11:06:54.000Z",
            "content_html": "<div class=\"note warning\">\n<p>本系列暴死，不会更新了。</p>\n</div>\n<div class=\"note info\">\n<p>该系列为本人的学习笔记，主要由本人整理书写而成。部分内容来自教材、视频课程等，不能保证完全原创性。</p>\n</div>\n<p>萌新的学习笔记，写错了恳请斧正。</p>\n<h3 id=\"c简介\"><a class=\"anchor\" href=\"#c简介\">#</a> C++ 简介</h3>\n<p>C++ 是由 Bjarne Stroustrup 在上世纪 80 年代开发的一款基于 C 语音的编程语言。一开始是作为 C 语言的完善与改进，后来随着一次次标准化更新，已经脱胎换骨了。但是<strong> C + 依旧向下兼容大部分 C 语言代码</strong>。</p>\n<p>这一篇笔记先从一些比较基础的地方讲其与 C 语言的区别。</p>\n<h3 id=\"c的关键字c98标准\"><a class=\"anchor\" href=\"#c的关键字c98标准\">#</a> C++ 的关键字（C++98 标准）</h3>\n<p>首先 C 语言只有 32 个关键字，而 C++98 却有 63 个关键字，C++11 及之后的标准中甚至更多。</p>\n<p>具体有哪些可以点下面的链接查看：</p>\n<p><div class=\"links\"><div class=\"item\" title=\"C/C++参考手册\" style=\"--block-color:#39c5bb;\"><span class=\"exturl image\" data-url=\"aHR0cHM6Ly96aC5jcHByZWZlcmVuY2UuY29tL3cvY3BwL2tleXdvcmQ=\" data-background-image=\"/images/404.png\"></span>\n          <div class=\"info\">\n          <span class=\"exturl title\" data-url=\"aHR0cHM6Ly96aC5jcHByZWZlcmVuY2UuY29tL3cvY3BwL2tleXdvcmQ=\">C/C++参考手册</span>\n          <p class=\"desc\">C++关键词</p>\n          </div></div></div></p>\n<h3 id=\"命名空间\"><a class=\"anchor\" href=\"#命名空间\">#</a> 命名空间</h3>\n<p>在 C 语言中，我们能遇到这样的情况：想要用的函数名、变量名在库中已经存在，因此不得不改名。</p>\n<p>而在 C++ 中，我们会遇到更多的库，其中有海量的函数，再加上我们自己会写的函数，命名重复的问题就凸显出来。</p>\n<p>因此，C++ 就引入了<strong>命名空间</strong>的概念，用以<mark>对标识符的名称进行本地化，以避免命名冲突或者名字污染</mark>。</p>\n<p>其原理大致可以理解为把各个函数放到各自的命名空间中，同一个命名空间内还是不能重名，但是不同命名空间之间可以有重名的函数（通过命名空间来区分）。</p>\n<h4 id=\"定义命名空间\"><a class=\"anchor\" href=\"#定义命名空间\">#</a> 定义命名空间</h4>\n<p>定义一个命名空间要使用关键字 <code>namespace</code> ，其定义方式与定义结构体类似（也同样可以嵌套）：</p>\n<figure class=\"highlight cpp\"><figcaption data-lang=\"C++\"></figcaption><table><tr><td data-num=\"1\"></td><td><pre><span class=\"token keyword\">int</span> rand<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"2\"></td><td><pre><span class=\"token keyword\">int</span> <span class=\"token function\">Add</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">int</span> Adder1<span class=\"token punctuation\">,</span> <span class=\"token keyword\">int</span> Adder2<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"3\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"4\"></td><td><pre>    <span class=\"token keyword\">return</span> Adder1 <span class=\"token operator\">+</span> Adder2<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"5\"></td><td><pre><span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"6\"></td><td><pre></pre></td></tr><tr><td data-num=\"7\"></td><td><pre><span class=\"token keyword\">namespace</span> ExampleSpace1</pre></td></tr><tr><td data-num=\"8\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"9\"></td><td><pre>    <span class=\"token keyword\">int</span> rand<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"10\"></td><td><pre>    <span class=\"token keyword\">int</span> <span class=\"token function\">Add</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">int</span> Adder1<span class=\"token punctuation\">,</span> <span class=\"token keyword\">int</span> Adder2<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"11\"></td><td><pre>    <span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"12\"></td><td><pre>        <span class=\"token keyword\">return</span> Adder1 <span class=\"token operator\">+</span> Adder2<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"13\"></td><td><pre>    <span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"14\"></td><td><pre><span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"15\"></td><td><pre></pre></td></tr><tr><td data-num=\"16\"></td><td><pre><span class=\"token keyword\">namespace</span> ExampleSpace2</pre></td></tr><tr><td data-num=\"17\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"18\"></td><td><pre>    <span class=\"token keyword\">int</span> rand<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"19\"></td><td><pre>    <span class=\"token keyword\">int</span> <span class=\"token function\">Add</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">int</span> Adder1<span class=\"token punctuation\">,</span> <span class=\"token keyword\">int</span> Adder2<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"20\"></td><td><pre>    <span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"21\"></td><td><pre>        <span class=\"token keyword\">return</span> Adder1 <span class=\"token operator\">+</span> Adder2<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"22\"></td><td><pre>    <span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"23\"></td><td><pre>    <span class=\"token keyword\">namespace</span> ExampleSpace3</pre></td></tr><tr><td data-num=\"24\"></td><td><pre>\t<span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"25\"></td><td><pre>        <span class=\"token keyword\">int</span> rand<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"26\"></td><td><pre>        <span class=\"token keyword\">int</span> <span class=\"token function\">Add</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">int</span> Adder1<span class=\"token punctuation\">,</span> <span class=\"token keyword\">int</span> Adder2<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"27\"></td><td><pre>        <span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"28\"></td><td><pre>            <span class=\"token keyword\">return</span> Adder1 <span class=\"token operator\">+</span> Adder2<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"29\"></td><td><pre>        <span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"30\"></td><td><pre>\t<span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"31\"></td><td><pre><span class=\"token punctuation\">&#125;</span></pre></td></tr></table></figure><p>如上方所示，我们在全局、ExampleSpace1、ExampleSpace2、ExampleSpace2 中的 ExampleSpace3 中分别定义了整型变量 rand 和函数 Add。但是由于其所处命名空间是不同的，所以不会出现问题。</p>\n<p>另外，在同一个工程中，可以有多个同名的命名空间，它们最后会被 “合并起来”，比方说我们可以在 test1.h 中定义命名空间 Test：</p>\n<figure class=\"highlight cpp\"><figcaption data-lang=\"C++\"><span>test1.h</span></figcaption><table><tr><td data-num=\"1\"></td><td><pre><span class=\"token keyword\">namespace</span> Test</pre></td></tr><tr><td data-num=\"2\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"3\"></td><td><pre>    <span class=\"token keyword\">int</span> a<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"4\"></td><td><pre>    <span class=\"token keyword\">int</span> b<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"5\"></td><td><pre><span class=\"token punctuation\">&#125;</span></pre></td></tr></table></figure><p>然后在 test2.h 中继续定义命名空间 Test：</p>\n<figure class=\"highlight cpp\"><figcaption data-lang=\"C++\"><span>test2.h</span></figcaption><table><tr><td data-num=\"1\"></td><td><pre><span class=\"token keyword\">namespace</span> Test</pre></td></tr><tr><td data-num=\"2\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"3\"></td><td><pre>    <span class=\"token keyword\">int</span> c<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"4\"></td><td><pre>    <span class=\"token keyword\">int</span> d<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"5\"></td><td><pre><span class=\"token punctuation\">&#125;</span></pre></td></tr></table></figure><p>那么在之后使用命名空间 Test 时，两边的内容就相当于 “合并” 起来作为一个命名空间。</p>\n<h4 id=\"展开使用命名空间\"><a class=\"anchor\" href=\"#展开使用命名空间\">#</a> 展开（使用）命名空间</h4>\n<p>那么我们应该如何使用命名空间呢？以下面这段为例：</p>\n<figure class=\"highlight cpp\"><figcaption data-lang=\"C++\"></figcaption><table><tr><td data-num=\"1\"></td><td><pre><span class=\"token keyword\">int</span> a<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"2\"></td><td><pre></pre></td></tr><tr><td data-num=\"3\"></td><td><pre><span class=\"token keyword\">namespace</span> ExampleSpace1</pre></td></tr><tr><td data-num=\"4\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"5\"></td><td><pre>    <span class=\"token keyword\">int</span> a<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"6\"></td><td><pre>    <span class=\"token keyword\">int</span> b<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"7\"></td><td><pre><span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"8\"></td><td><pre></pre></td></tr><tr><td data-num=\"9\"></td><td><pre><span class=\"token keyword\">namespace</span> ExampleSpace2</pre></td></tr><tr><td data-num=\"10\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"11\"></td><td><pre>    <span class=\"token keyword\">int</span> c<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"12\"></td><td><pre>    <span class=\"token keyword\">namespace</span> ExampleSpace3</pre></td></tr><tr><td data-num=\"13\"></td><td><pre>\t<span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"14\"></td><td><pre>        <span class=\"token keyword\">int</span> d<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"15\"></td><td><pre>\t<span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"16\"></td><td><pre><span class=\"token punctuation\">&#125;</span></pre></td></tr></table></figure><p>使用命名空间一般有三种方式。</p>\n<h5 id=\"方式命名空间名称加作用域限定符\"><a class=\"anchor\" href=\"#方式命名空间名称加作用域限定符\">#</a> 方式：命名空间名称加作用域限定符</h5>\n<p>两个英文冒号连在一起就是<mark>作用域限定符（::）</mark>。</p>\n<figure class=\"highlight cpp\"><figcaption data-lang=\"C++\"></figcaption><table><tr><td data-num=\"1\"></td><td><pre><span class=\"token keyword\">int</span> <span class=\"token function\">main</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"2\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"3\"></td><td><pre>    <span class=\"token function\">printf</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"%d\\n\"</span><span class=\"token punctuation\">,</span> a<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\t<span class=\"token comment\">// 未加限定时访问全局域的 a</span></pre></td></tr><tr><td data-num=\"4\"></td><td><pre>    <span class=\"token function\">printf</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"%d\\n\"</span><span class=\"token punctuation\">,</span> <span class=\"token double-colon punctuation\">::</span>a<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\t<span class=\"token comment\">// 限定为空同样访问全局域的 a</span></pre></td></tr><tr><td data-num=\"5\"></td><td><pre>    <span class=\"token function\">printf</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"%d\\n\"</span><span class=\"token punctuation\">,</span> ExampleSpace1<span class=\"token double-colon punctuation\">::</span>a<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\t<span class=\"token comment\">// 访问 ExampleSpace1 中的 a</span></pre></td></tr><tr><td data-num=\"6\"></td><td><pre>    <span class=\"token function\">printf</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"%d\\n\"</span><span class=\"token punctuation\">,</span> ExampleSpace2<span class=\"token double-colon punctuation\">::</span>a<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\t<span class=\"token comment\">// 访问 ExampleSpace2 中的 a</span></pre></td></tr><tr><td data-num=\"7\"></td><td><pre>    <span class=\"token function\">printf</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"%d\\n\"</span><span class=\"token punctuation\">,</span> ExampleSpace2<span class=\"token double-colon punctuation\">::</span>ExampleSpace3<span class=\"token double-colon punctuation\">::</span>a<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\t<span class=\"token comment\">// 访问 ExampleSpace2 中的 ExampleSpace3 中的 a</span></pre></td></tr><tr><td data-num=\"8\"></td><td><pre><span class=\"token punctuation\">&#125;</span></pre></td></tr></table></figure><h5 id=\"方式用using关键字引入命名空间内容\"><a class=\"anchor\" href=\"#方式用using关键字引入命名空间内容\">#</a> 方式：用 using 关键字引入命名空间内容</h5>\n<p>比方说这样就能引入 ExampleSpace1 中的 b。</p>\n<figure class=\"highlight cpp\"><figcaption data-lang=\"C++\"></figcaption><table><tr><td data-num=\"1\"></td><td><pre><span class=\"token keyword\">using</span> ExampleSpace1<span class=\"token double-colon punctuation\">::</span>b<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"2\"></td><td><pre></pre></td></tr><tr><td data-num=\"3\"></td><td><pre><span class=\"token keyword\">int</span> <span class=\"token function\">main</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"4\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"5\"></td><td><pre>\tcout <span class=\"token operator\">&lt;&lt;</span> b <span class=\"token operator\">&lt;&lt;</span> endl<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"6\"></td><td><pre>\t<span class=\"token keyword\">return</span> <span class=\"token number\">0</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"7\"></td><td><pre><span class=\"token punctuation\">&#125;</span></pre></td></tr></table></figure><p>这里我们不能使用引入 ExampleSpace1 中的 a，因为全局中已经存在一个 a 了，产生多义性问题。</p>\n<h5 id=\"方式用using-namespace引入整个命名空间\"><a class=\"anchor\" href=\"#方式用using-namespace引入整个命名空间\">#</a> 方式：用 using namespace 引入整个命名空间</h5>\n<p>如果某个命名空间里面有大量的内容，我们总不能一个一个去引入，所以我们可以直接引入整个命名空间：</p>\n<figure class=\"highlight cpp\"><figcaption data-lang=\"C++\"></figcaption><table><tr><td data-num=\"1\"></td><td><pre><span class=\"token comment\">// 注意嵌套的情况下不能直接写 ExampleSpace3</span></pre></td></tr><tr><td data-num=\"2\"></td><td><pre><span class=\"token keyword\">using</span> <span class=\"token keyword\">namespace</span> ExampleSpace2<span class=\"token double-colon punctuation\">::</span>ExampleSpace3<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"3\"></td><td><pre></pre></td></tr><tr><td data-num=\"4\"></td><td><pre><span class=\"token keyword\">int</span> <span class=\"token function\">main</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"5\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"6\"></td><td><pre>\tcout <span class=\"token operator\">&lt;&lt;</span> d <span class=\"token operator\">&lt;&lt;</span> endl<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"7\"></td><td><pre>\t<span class=\"token keyword\">return</span> <span class=\"token number\">0</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"8\"></td><td><pre><span class=\"token punctuation\">&#125;</span></pre></td></tr></table></figure><p>那如果我们<strong>引入 ExampleSpace2 的话，能不能直接使用 ExampleSpace3 中的内容呢？</strong></p>\n<p>答案是<strong>否定</strong>的，但是如果引入 ExampleSpace2 的话我们就可以写成这样了：</p>\n<figure class=\"highlight cpp\"><figcaption data-lang=\"C++\"></figcaption><table><tr><td data-num=\"1\"></td><td><pre><span class=\"token keyword\">using</span> <span class=\"token keyword\">namespace</span> ExampleSpace2<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"2\"></td><td><pre></pre></td></tr><tr><td data-num=\"3\"></td><td><pre><span class=\"token keyword\">int</span> <span class=\"token function\">main</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"4\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"5\"></td><td><pre>\tcout <span class=\"token operator\">&lt;&lt;</span> ExampleSpace3<span class=\"token double-colon punctuation\">::</span>d <span class=\"token operator\">&lt;&lt;</span> endl<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"6\"></td><td><pre>\t<span class=\"token keyword\">return</span> <span class=\"token number\">0</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"7\"></td><td><pre><span class=\"token punctuation\">&#125;</span></pre></td></tr></table></figure><p>此时就不用写成 ExampleSpace2::ExampleSpace3::d（虽然也行）。</p>\n<h5 id=\"注意命名空间展开位置\"><a class=\"anchor\" href=\"#注意命名空间展开位置\">#</a> 注意：命名空间展开位置</h5>\n<p><mark>展开（使用）命名空间是可以在作用域中进行的，不是说一定在全局中展开</mark>，比方说：</p>\n<figure class=\"highlight cpp\"><figcaption data-lang=\"C++\"></figcaption><table><tr><td data-num=\"1\"></td><td><pre><span class=\"token keyword\">int</span> <span class=\"token function\">main</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"2\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"3\"></td><td><pre>\t<span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span><span class=\"token boolean\">true</span><span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"4\"></td><td><pre>\t<span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"5\"></td><td><pre>\t\t<span class=\"token keyword\">using</span> <span class=\"token keyword\">namespace</span> ExampleSpace2<span class=\"token double-colon punctuation\">::</span>ExampleSpace3<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"6\"></td><td><pre>\t\tcout <span class=\"token operator\">&lt;&lt;</span> d <span class=\"token operator\">&lt;&lt;</span> endl<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"7\"></td><td><pre>\t<span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"8\"></td><td><pre><span class=\"token punctuation\">&#125;</span></pre></td></tr></table></figure><h5 id=\"注意展开命名空间的实际含义\"><a class=\"anchor\" href=\"#注意展开命名空间的实际含义\">#</a> 注意：展开命名空间的实际含义</h5>\n<p><mark>比方说全局中的命名空间 ExampleSpace1 我们如果放在某作用域内展开，并不是说这个时候使用其中的变量或者函数或者别的什么就是该作用域内的东西了。这些东西依旧存在于全局，我们这里的展开只是给了一个权限使得我们能在这个作用域内定向的使用 ExampleSpace1 中的东西。</mark></p>\n<p>这里我们可以看一个例子，比方说下面这段代码的运行结果是 10，不会报错：</p>\n<figure class=\"highlight cpp\"><figcaption data-lang=\"C++\"></figcaption><table><tr><td data-num=\"1\"></td><td><pre><span class=\"token keyword\">int</span> a <span class=\"token operator\">=</span> <span class=\"token number\">0</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"2\"></td><td><pre></pre></td></tr><tr><td data-num=\"3\"></td><td><pre><span class=\"token keyword\">int</span> <span class=\"token function\">main</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"4\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"5\"></td><td><pre>\t<span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span><span class=\"token boolean\">true</span><span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"6\"></td><td><pre>\t<span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"7\"></td><td><pre>\t\t<span class=\"token keyword\">int</span> a <span class=\"token operator\">=</span> <span class=\"token number\">10</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"8\"></td><td><pre>\t\tcout <span class=\"token operator\">&lt;&lt;</span> a <span class=\"token operator\">&lt;&lt;</span> endl<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"9\"></td><td><pre>\t<span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"10\"></td><td><pre><span class=\"token punctuation\">&#125;</span></pre></td></tr></table></figure><p>因为编译器会先在作用域内寻找符合的变量，这可以与全局中的变量共存。</p>\n<p>但是如果写成这样，就会报错了：</p>\n<figure class=\"highlight cpp\"><figcaption data-lang=\"C++\"></figcaption><table><tr><td data-num=\"1\"></td><td><pre><span class=\"token keyword\">int</span> a <span class=\"token operator\">=</span> <span class=\"token number\">0</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"2\"></td><td><pre></pre></td></tr><tr><td data-num=\"3\"></td><td><pre><span class=\"token keyword\">namespace</span> X</pre></td></tr><tr><td data-num=\"4\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"5\"></td><td><pre>\t<span class=\"token keyword\">int</span> a <span class=\"token operator\">=</span> <span class=\"token number\">10</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"6\"></td><td><pre><span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"7\"></td><td><pre></pre></td></tr><tr><td data-num=\"8\"></td><td><pre><span class=\"token keyword\">int</span> <span class=\"token function\">main</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"9\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"10\"></td><td><pre>\t<span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span><span class=\"token boolean\">true</span><span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"11\"></td><td><pre>\t<span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"12\"></td><td><pre>\t\t<span class=\"token keyword\">using</span> <span class=\"token keyword\">namespace</span> X<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"13\"></td><td><pre>\t\tcout <span class=\"token operator\">&lt;&lt;</span> a <span class=\"token operator\">&lt;&lt;</span> endl<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"14\"></td><td><pre>\t<span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"15\"></td><td><pre><span class=\"token punctuation\">&#125;</span></pre></td></tr></table></figure><p><strong>这就是因为展开命名空间实际上只是给予了访问权限并不是真正的展开。编译器先在作用域内没有找到 a，然后在全局中寻找，而有了命名空间 X 访问权限的编译器此时就在全局中发现了两个 a，一个直接写在全局中，另一个写在命名空间 X 中。这就产生了多义性错误。</strong></p>\n<h3 id=\"c的输入与输出\"><a class=\"anchor\" href=\"#c的输入与输出\">#</a> C++ 的输入与输出</h3>\n<h4 id=\"c中的标准输入输出库与标准库命名空间\"><a class=\"anchor\" href=\"#c中的标准输入输出库与标准库命名空间\">#</a> C++ 中的标准输入输出库与标准库命名空间</h4>\n<p>我们看看 C++ 中的 Hello World! 程序：</p>\n<figure class=\"highlight cpp\"><figcaption data-lang=\"C++\"></figcaption><table><tr><td data-num=\"1\"></td><td><pre><span class=\"token macro property\"><span class=\"token directive-hash\">#</span><span class=\"token directive keyword\">include</span> <span class=\"token string\">&lt;iostream></span></span></pre></td></tr><tr><td data-num=\"2\"></td><td><pre><span class=\"token keyword\">using</span> <span class=\"token keyword\">namespace</span> std<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"3\"></td><td><pre></pre></td></tr><tr><td data-num=\"4\"></td><td><pre><span class=\"token keyword\">int</span> <span class=\"token function\">main</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"5\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"6\"></td><td><pre>    cout <span class=\"token operator\">&lt;&lt;</span> <span class=\"token string\">\"Hello world!\"</span> <span class=\"token operator\">&lt;&lt;</span> endl<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"7\"></td><td><pre>    <span class=\"token keyword\">return</span> <span class=\"token number\">0</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"8\"></td><td><pre><span class=\"token punctuation\">&#125;</span></pre></td></tr></table></figure><p>第一行包含的库 <code>&lt;iostream&gt;</code>  是 C++ 的标准输入输出库，可以理解为之前 C 语言的 <code>&lt;stdio.h&gt;</code> ，但是内容更丰富全面。（C++ 的库文件一般不带 <code>.h</code>  后缀）</p>\n<p>第二行中的命名空间 std 就是 C++ 中的标准库命名空间，C++ 所有标准库的定义都实现在这个命名空间，我们必须包含这个命名空间才能使用其中的内容。</p>\n<p>第六行中的输出方式是 C++ 特有的 IO 流方式，其中 <code>&lt;&lt;</code>  是流插入运算符，与之相对的 <code>&gt;&gt;</code>  是流提取运算符。使用这种方式进行输入输出比较方便，不需要手动控制格式。其更具体的使用与原理等后面会学。</p>\n<h3 id=\"缺省参数\"><a class=\"anchor\" href=\"#缺省参数\">#</a> 缺省参数</h3>\n<h4 id=\"缺省参数的概念\"><a class=\"anchor\" href=\"#缺省参数的概念\">#</a> 缺省参数的概念</h4>\n<p>缺省参数就是在声明或者定义函数时为其参数设定一个缺省值（默认值），在调用这个函数时，如果没有指定这个参数就使用其缺省值，比方说：</p>\n<figure class=\"highlight cpp\"><figcaption data-lang=\"C++\"></figcaption><table><tr><td data-num=\"1\"></td><td><pre><span class=\"token macro property\"><span class=\"token directive-hash\">#</span><span class=\"token directive keyword\">include</span> <span class=\"token string\">&lt;iostream></span></span></pre></td></tr><tr><td data-num=\"2\"></td><td><pre></pre></td></tr><tr><td data-num=\"3\"></td><td><pre><span class=\"token keyword\">using</span> <span class=\"token keyword\">namespace</span> std<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"4\"></td><td><pre></pre></td></tr><tr><td data-num=\"5\"></td><td><pre><span class=\"token keyword\">void</span> <span class=\"token function\">func</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">int</span> a<span class=\"token punctuation\">,</span> <span class=\"token keyword\">int</span> b <span class=\"token operator\">=</span> <span class=\"token number\">10</span><span class=\"token punctuation\">,</span> <span class=\"token keyword\">int</span> c <span class=\"token operator\">=</span> <span class=\"token number\">20</span><span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"6\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"7\"></td><td><pre>\tcout <span class=\"token operator\">&lt;&lt;</span> <span class=\"token string\">\"a = \"</span> <span class=\"token operator\">&lt;&lt;</span> a <span class=\"token operator\">&lt;&lt;</span> <span class=\"token string\">\", b = \"</span> <span class=\"token operator\">&lt;&lt;</span> b <span class=\"token operator\">&lt;&lt;</span> <span class=\"token string\">\", c = \"</span> <span class=\"token operator\">&lt;&lt;</span> c <span class=\"token operator\">&lt;&lt;</span> endl<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"8\"></td><td><pre><span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"9\"></td><td><pre></pre></td></tr><tr><td data-num=\"10\"></td><td><pre><span class=\"token keyword\">int</span> <span class=\"token function\">main</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"11\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"12\"></td><td><pre>\t<span class=\"token function\">func</span><span class=\"token punctuation\">(</span><span class=\"token number\">1</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"13\"></td><td><pre>\t<span class=\"token function\">func</span><span class=\"token punctuation\">(</span><span class=\"token number\">1</span><span class=\"token punctuation\">,</span> <span class=\"token number\">2</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"14\"></td><td><pre>\t<span class=\"token function\">func</span><span class=\"token punctuation\">(</span><span class=\"token number\">1</span><span class=\"token punctuation\">,</span> <span class=\"token number\">2</span><span class=\"token punctuation\">,</span> <span class=\"token number\">3</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"15\"></td><td><pre>\t<span class=\"token keyword\">return</span> <span class=\"token number\">0</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"16\"></td><td><pre><span class=\"token punctuation\">&#125;</span></pre></td></tr></table></figure><p>该程序输出为：</p>\n<figure class=\"highlight bash\"><figcaption data-lang=\"bash\"></figcaption><table><tr><td data-num=\"1\"></td><td><pre>a <span class=\"token operator\">=</span> <span class=\"token number\">1</span>, b <span class=\"token operator\">=</span> <span class=\"token number\">10</span>, c <span class=\"token operator\">=</span> <span class=\"token number\">20</span></pre></td></tr><tr><td data-num=\"2\"></td><td><pre>a <span class=\"token operator\">=</span> <span class=\"token number\">1</span>, b <span class=\"token operator\">=</span> <span class=\"token number\">2</span>, c <span class=\"token operator\">=</span> <span class=\"token number\">20</span></pre></td></tr><tr><td data-num=\"3\"></td><td><pre>a <span class=\"token operator\">=</span> <span class=\"token number\">1</span>, b <span class=\"token operator\">=</span> <span class=\"token number\">2</span>, c <span class=\"token operator\">=</span> <span class=\"token number\">3</span></pre></td></tr></table></figure><h4 id=\"注意缺省参数在参数列表中的位置\"><a class=\"anchor\" href=\"#注意缺省参数在参数列表中的位置\">#</a> 注意：缺省参数在参数列表中的位置</h4>\n<p><strong>一旦某个参数被赋予了默认值，其右侧的所有参数也必须有默认值。这是因为实参的传递是按参数列表从左到右的顺序进行的。</strong></p>\n<p>也就是说，不能写出下面这种东西：</p>\n<figure class=\"highlight cpp\"><figcaption data-lang=\"C++\"></figcaption><table><tr><td data-num=\"1\"></td><td><pre><span class=\"token keyword\">void</span> <span class=\"token function\">func</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">int</span> a<span class=\"token punctuation\">,</span> <span class=\"token keyword\">int</span> b <span class=\"token operator\">=</span> <span class=\"token number\">10</span><span class=\"token punctuation\">,</span> <span class=\"token keyword\">int</span> c<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"2\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"3\"></td><td><pre>\tcout <span class=\"token operator\">&lt;&lt;</span> <span class=\"token string\">\"a = \"</span> <span class=\"token operator\">&lt;&lt;</span> a <span class=\"token operator\">&lt;&lt;</span> <span class=\"token string\">\", b = \"</span> <span class=\"token operator\">&lt;&lt;</span> b <span class=\"token operator\">&lt;&lt;</span> <span class=\"token string\">\", c = \"</span> <span class=\"token operator\">&lt;&lt;</span> c <span class=\"token operator\">&lt;&lt;</span> endl<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"4\"></td><td><pre><span class=\"token punctuation\">&#125;</span></pre></td></tr></table></figure><p>因为只要 b 有默认值，它右边的 c 也要有默认值才行。</p>\n<h4 id=\"注意函数有声明时缺省参数只能出现一次\"><a class=\"anchor\" href=\"#注意函数有声明时缺省参数只能出现一次\">#</a> 注意：函数有声明时缺省参数只能出现一次</h4>\n<p>如果函数同时有声明和定义，并且分开书写，那么<strong>默认参数应只在其中之一中指定</strong>，<strong>通常是在函数声明中</strong>。这是为了防止缺省参数被重定义：</p>\n<figure class=\"highlight cpp\"><figcaption data-lang=\"C++\"></figcaption><table><tr><td data-num=\"1\"></td><td><pre><span class=\"token macro property\"><span class=\"token directive-hash\">#</span><span class=\"token directive keyword\">include</span> <span class=\"token string\">&lt;iostream></span></span></pre></td></tr><tr><td data-num=\"2\"></td><td><pre></pre></td></tr><tr><td data-num=\"3\"></td><td><pre><span class=\"token keyword\">using</span> <span class=\"token keyword\">namespace</span> std<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"4\"></td><td><pre></pre></td></tr><tr><td data-num=\"5\"></td><td><pre><span class=\"token keyword\">void</span> <span class=\"token function\">func</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">int</span> a<span class=\"token punctuation\">,</span> <span class=\"token keyword\">int</span> b <span class=\"token operator\">=</span> <span class=\"token number\">10</span><span class=\"token punctuation\">,</span> <span class=\"token keyword\">int</span> c <span class=\"token operator\">=</span> <span class=\"token number\">20</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"6\"></td><td><pre></pre></td></tr><tr><td data-num=\"7\"></td><td><pre><span class=\"token keyword\">void</span> <span class=\"token function\">func</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">int</span> a<span class=\"token punctuation\">,</span> <span class=\"token keyword\">int</span> b<span class=\"token punctuation\">,</span> <span class=\"token keyword\">int</span> c<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"8\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"9\"></td><td><pre>\tcout <span class=\"token operator\">&lt;&lt;</span> <span class=\"token string\">\"a = \"</span> <span class=\"token operator\">&lt;&lt;</span> a <span class=\"token operator\">&lt;&lt;</span> <span class=\"token string\">\", b = \"</span> <span class=\"token operator\">&lt;&lt;</span> b <span class=\"token operator\">&lt;&lt;</span> <span class=\"token string\">\", c = \"</span> <span class=\"token operator\">&lt;&lt;</span> c <span class=\"token operator\">&lt;&lt;</span> endl<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"10\"></td><td><pre><span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"11\"></td><td><pre></pre></td></tr><tr><td data-num=\"12\"></td><td><pre><span class=\"token keyword\">int</span> <span class=\"token function\">main</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"13\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"14\"></td><td><pre>\t<span class=\"token function\">func</span><span class=\"token punctuation\">(</span><span class=\"token number\">1</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"15\"></td><td><pre>\t<span class=\"token function\">func</span><span class=\"token punctuation\">(</span><span class=\"token number\">1</span><span class=\"token punctuation\">,</span> <span class=\"token number\">2</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"16\"></td><td><pre>\t<span class=\"token function\">func</span><span class=\"token punctuation\">(</span><span class=\"token number\">1</span><span class=\"token punctuation\">,</span> <span class=\"token number\">2</span><span class=\"token punctuation\">,</span> <span class=\"token number\">3</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"17\"></td><td><pre>\t<span class=\"token keyword\">return</span> <span class=\"token number\">0</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"18\"></td><td><pre><span class=\"token punctuation\">&#125;</span></pre></td></tr></table></figure><h4 id=\"注意缺省值必须是常量或者全局变量\"><a class=\"anchor\" href=\"#注意缺省值必须是常量或者全局变量\">#</a> 注意：缺省值必须是常量或者全局变量</h4>\n<h3 id=\"函数重载\"><a class=\"anchor\" href=\"#函数重载\">#</a> 函数重载</h3>\n<h4 id=\"函数重载的概念\"><a class=\"anchor\" href=\"#函数重载的概念\">#</a> 函数重载的概念</h4>\n<p>C++ 支持在同一个作用域中声明几个有相同函数名的函数，前提是他们能够通过参数列表区分开来。</p>\n<p>重载函数的出现，方便了功能类似但参数类型不同的函数，举个例子：</p>\n<figure class=\"highlight cpp\"><figcaption data-lang=\"C++\"></figcaption><table><tr><td data-num=\"1\"></td><td><pre><span class=\"token macro property\"><span class=\"token directive-hash\">#</span><span class=\"token directive keyword\">include</span> <span class=\"token string\">&lt;iostream></span></span></pre></td></tr><tr><td data-num=\"2\"></td><td><pre></pre></td></tr><tr><td data-num=\"3\"></td><td><pre><span class=\"token keyword\">using</span> <span class=\"token keyword\">namespace</span> std<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"4\"></td><td><pre></pre></td></tr><tr><td data-num=\"5\"></td><td><pre><span class=\"token keyword\">void</span> <span class=\"token function\">print</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">int</span> a<span class=\"token punctuation\">)</span> </pre></td></tr><tr><td data-num=\"6\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"7\"></td><td><pre>\tcout <span class=\"token operator\">&lt;&lt;</span> <span class=\"token string\">\"int: \"</span> <span class=\"token operator\">&lt;&lt;</span> a <span class=\"token operator\">&lt;&lt;</span> endl<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"8\"></td><td><pre><span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"9\"></td><td><pre></pre></td></tr><tr><td data-num=\"10\"></td><td><pre><span class=\"token keyword\">void</span> <span class=\"token function\">print</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">double</span> a<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"11\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"12\"></td><td><pre>\tcout <span class=\"token operator\">&lt;&lt;</span> <span class=\"token string\">\"double: \"</span> <span class=\"token operator\">&lt;&lt;</span> a <span class=\"token operator\">&lt;&lt;</span> endl<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"13\"></td><td><pre><span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"14\"></td><td><pre></pre></td></tr><tr><td data-num=\"15\"></td><td><pre><span class=\"token keyword\">void</span> <span class=\"token function\">print</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">char</span> a<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"16\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"17\"></td><td><pre>\tcout <span class=\"token operator\">&lt;&lt;</span> <span class=\"token string\">\"char: \"</span> <span class=\"token operator\">&lt;&lt;</span> a <span class=\"token operator\">&lt;&lt;</span> endl<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"18\"></td><td><pre><span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"19\"></td><td><pre></pre></td></tr><tr><td data-num=\"20\"></td><td><pre><span class=\"token keyword\">int</span> <span class=\"token function\">main</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"21\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"22\"></td><td><pre>\t<span class=\"token function\">print</span><span class=\"token punctuation\">(</span><span class=\"token number\">10</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"23\"></td><td><pre>\t<span class=\"token function\">print</span><span class=\"token punctuation\">(</span><span class=\"token number\">10.5</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"24\"></td><td><pre>\t<span class=\"token function\">print</span><span class=\"token punctuation\">(</span><span class=\"token char\">'A'</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"25\"></td><td><pre></pre></td></tr><tr><td data-num=\"26\"></td><td><pre>\t<span class=\"token keyword\">return</span> <span class=\"token number\">0</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"27\"></td><td><pre><span class=\"token punctuation\">&#125;</span></pre></td></tr></table></figure><p>其输出为：</p>\n<figure class=\"highlight bash\"><figcaption data-lang=\"bash\"></figcaption><table><tr><td data-num=\"1\"></td><td><pre>int: <span class=\"token number\">10</span></pre></td></tr><tr><td data-num=\"2\"></td><td><pre>double: <span class=\"token number\">10.5</span></pre></td></tr><tr><td data-num=\"3\"></td><td><pre>char: A</pre></td></tr></table></figure><h4 id=\"函数重载实现的原理\"><a class=\"anchor\" href=\"#函数重载实现的原理\">#</a> 函数重载实现的原理</h4>\n<p>在<strong> C 语言笔记 #36</strong> 中，我们就说过 C/C++ 代码生成可执行程序要经过预处理、编译、汇编、链接几个阶段。</p>\n<p>每一个源代码文件都要经历预处理、编译和汇编过程生成对应的 <code>.o</code>  文件（Linux 下）或者 <code>.obj</code>  文件（Windows 下）。最终它们与链接库通过链接器链接起来变成可执行程序。</p>\n<p>代码中调用函数的步骤在汇编后实际上就变成了跳转到函数指令执行地址。一般来说，在多文件项目中，链接前每一个头文件是独立的，<strong>不知道要调用的函数地址在哪。此时就会用一个 “记号” 来代替，而在链接阶段，链接器通过这个 “记号” 在符号表中寻找对应函数的地址并填进去</strong>。</p>\n<p>而在 C 语言中，这个记号仅由函数名决定，因此如果有重名函数就无法被链接器区分。</p>\n<p><mark>在 C++ 中，这个记号有命名空间、函数名、参数列表多方面决定，因此能够被链接器区分开来。</mark></p>\n<ul>\n<li>\n<p>对于 Linux 环境的 g++ 编译器，这个记号由以下几个部分组成：</p>\n<p><code>'_Z'</code>  加上 <code>函数名长度</code> 加上 <code>函数名</code> 加上各参数类型的缩写。</p>\n<p>比方说函数 <code>int Add(int a, int b);</code>  对应的记号是：_Z3Addii</p>\n<p>而函数 <code>void func(int a, float b, int* p);</code>  对应的记号是：_Z4funcifPi</p>\n</li>\n<li>\n<p>对于 Windows 环境下的名字修饰规则就比较复杂，记号由以下部分组成：</p>\n<p><code>'?'</code>  加上 <code>函数名</code> 加上 <code>'@'</code>  加上 <code>命名空间（如果有嵌套用'@'隔开）</code> 加上 <code>'@'</code>  加上 <code>代表函数调用类型、参数、返回值的一串代码（具体符号含义复杂不做介绍）</code> 加上 <code>'@Z'</code></p>\n<p>比方说对于函数 <code>int func(int);</code>  对应的记号是： ?func@@YAHH@Z</p>\n<p>而函数 <code>int C::C2::func(int);</code>  对应的记号是：?func@C2@C@@AAEHH@Z</p>\n</li>\n</ul>\n<h3 id=\"引用\"><a class=\"anchor\" href=\"#引用\">#</a> 引用</h3>\n<h4 id=\"引用的概念\"><a class=\"anchor\" href=\"#引用的概念\">#</a> 引用的概念</h4>\n<p>在 C++ 中，引用是一个非常重要的特性，它为另一个已存在的变量提供了一个别名。引用主要用于函数参数传递和返回值，使得代码更加有效且易于理解。</p>\n<p>C++ 使用符号  <code>&amp;</code>  来声明引用，例如  <code>int&amp; ref = var;</code>  这里  <code>ref</code>  就成了  <code>var</code>  的一个引用，<mark>对引用的任何操作都是直接对原变量的操作</mark>。</p>\n<p>注意 1：引用在声明时必须被初始化，这是与指针最大的不同之一。一旦一个引用被初始化指向一个变量，它就不能被改变指向另一个变量。</p>\n<p>注意 2：引用必须连接到一块合法的内存，不能像指针那样可以有 <code>NULL</code>  值。</p>\n<h4 id=\"引用的操作权限\"><a class=\"anchor\" href=\"#引用的操作权限\">#</a> 引用的操作权限</h4>\n<p>不加修饰引用的操作权限是可读可写，而权限只能缩小不能扩大，因此不能对常量进行引用：</p>\n<figure class=\"highlight cpp\"><figcaption data-lang=\"C++\"></figcaption><table><tr><td data-num=\"1\"></td><td><pre><span class=\"token keyword\">const</span> <span class=\"token keyword\">int</span> a <span class=\"token operator\">=</span> <span class=\"token number\">10</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"2\"></td><td><pre><span class=\"token comment\">//int&amp; ra = a;\t//err，a 为常量只读，权限不能扩大</span></pre></td></tr><tr><td data-num=\"3\"></td><td><pre><span class=\"token keyword\">const</span> <span class=\"token keyword\">int</span><span class=\"token operator\">&amp;</span> ra <span class=\"token operator\">=</span> a<span class=\"token punctuation\">;</span>\t<span class=\"token comment\">//ok，const 修饰后 ra 也是只读的引用，权限不变</span></pre></td></tr><tr><td data-num=\"4\"></td><td><pre></pre></td></tr><tr><td data-num=\"5\"></td><td><pre><span class=\"token comment\">//int&amp; rb = 666;\t//err，666 是常量只读，权限不能扩大</span></pre></td></tr><tr><td data-num=\"6\"></td><td><pre><span class=\"token keyword\">const</span> <span class=\"token keyword\">int</span><span class=\"token operator\">&amp;</span> rb <span class=\"token operator\">=</span> <span class=\"token number\">666</span><span class=\"token punctuation\">;</span>\t<span class=\"token comment\">//ok</span></pre></td></tr><tr><td data-num=\"7\"></td><td><pre></pre></td></tr><tr><td data-num=\"8\"></td><td><pre><span class=\"token keyword\">double</span> pi <span class=\"token operator\">=</span> <span class=\"token number\">3.14</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"9\"></td><td><pre><span class=\"token comment\">//int&amp; rpi = pi;\t//err，类型不同</span></pre></td></tr><tr><td data-num=\"10\"></td><td><pre><span class=\"token keyword\">const</span> <span class=\"token keyword\">int</span><span class=\"token operator\">&amp;</span> rpi <span class=\"token operator\">=</span> pi<span class=\"token punctuation\">;</span>\t<span class=\"token comment\">//ok，这里发生隐式的类型转换变成 3</span></pre></td></tr></table></figure><h4 id=\"常引用\"><a class=\"anchor\" href=\"#常引用\">#</a> 常引用</h4>\n<p>对于上方的代码，我们注意到如果引用被 const 修饰，能够获得更高的灵活性。这被称为<mark>常引用</mark>。</p>\n<ul>\n<li>常引用可以引用常量，这使得我们能够在不修改原始数据的前提下，安全地使用或检查其值。</li>\n<li>常引用会延长临时对象的生命周期，当一个临时对象被一个常引用绑定时，该临时对象的生命周期会被延长，直到这个常引用的生命周期结束。</li>\n</ul>\n<h4 id=\"引用在函数中的使用场景\"><a class=\"anchor\" href=\"#引用在函数中的使用场景\">#</a> 引用在函数中的使用场景</h4>\n<h5 id=\"作参数\"><a class=\"anchor\" href=\"#作参数\">#</a> 作参数</h5>\n<p>使用引用作为函数参数的主要好处是能够直接操作调用者的变量，避免了数据的复制，从而提高效率。</p>\n<figure class=\"highlight cpp\"><figcaption data-lang=\"C++\"></figcaption><table><tr><td data-num=\"1\"></td><td><pre><span class=\"token keyword\">void</span> <span class=\"token function\">Swap</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">int</span><span class=\"token operator\">&amp;</span> a<span class=\"token punctuation\">,</span> <span class=\"token keyword\">int</span><span class=\"token operator\">&amp;</span> b<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"2\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"3\"></td><td><pre>    <span class=\"token keyword\">int</span> tmp <span class=\"token operator\">=</span> a<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"4\"></td><td><pre>    a <span class=\"token operator\">=</span> b<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"5\"></td><td><pre>    b <span class=\"token operator\">=</span> tmp<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"6\"></td><td><pre><span class=\"token punctuation\">&#125;</span></pre></td></tr></table></figure><h5 id=\"作返回值\"><a class=\"anchor\" href=\"#作返回值\">#</a> 作返回值</h5>\n<p>使用引用返回函数结果主要是为了避免返回值的拷贝，特别是当返回对象较大时。</p>\n<p>它还允许函数返回操作结果直接对应到调用者的某个变量或对象上。</p>\n<p>注意：<mark>确保返回的对象在函数返回后仍然存在，要不然不要使用！</mark></p>\n<p>比方说这段代码中返回的 n 被 static 修饰，在函数栈帧销毁后依旧存在，所以可用：</p>\n<figure class=\"highlight cpp\"><figcaption data-lang=\"C++\"></figcaption><table><tr><td data-num=\"1\"></td><td><pre><span class=\"token keyword\">int</span><span class=\"token operator\">&amp;</span> <span class=\"token function\">Count</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"2\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"3\"></td><td><pre>    <span class=\"token keyword\">static</span> <span class=\"token keyword\">int</span> n <span class=\"token operator\">=</span> <span class=\"token number\">0</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"4\"></td><td><pre>    n<span class=\"token operator\">++</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"5\"></td><td><pre>    <span class=\"token keyword\">return</span> n<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"6\"></td><td><pre><span class=\"token punctuation\">&#125;</span></pre></td></tr></table></figure><p>再比方说这段代码中返回的是 array 数组中的内容，不是栈帧中开辟的局部变量，所以没问题：</p>\n<figure class=\"highlight cpp\"><figcaption data-lang=\"C++\"></figcaption><table><tr><td data-num=\"1\"></td><td><pre><span class=\"token macro property\"><span class=\"token directive-hash\">#</span><span class=\"token directive keyword\">include</span> <span class=\"token string\">&lt;iostream></span></span></pre></td></tr><tr><td data-num=\"2\"></td><td><pre><span class=\"token keyword\">using</span> <span class=\"token keyword\">namespace</span> std<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"3\"></td><td><pre></pre></td></tr><tr><td data-num=\"4\"></td><td><pre><span class=\"token keyword\">int</span><span class=\"token operator\">&amp;</span> <span class=\"token function\">getElement</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">int</span><span class=\"token operator\">*</span> array<span class=\"token punctuation\">,</span> <span class=\"token keyword\">int</span> index<span class=\"token punctuation\">)</span> </pre></td></tr><tr><td data-num=\"5\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"6\"></td><td><pre>    <span class=\"token keyword\">return</span> array<span class=\"token punctuation\">[</span>index<span class=\"token punctuation\">]</span><span class=\"token punctuation\">;</span>  <span class=\"token comment\">// 返回数组元素的引用</span></pre></td></tr><tr><td data-num=\"7\"></td><td><pre><span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"8\"></td><td><pre></pre></td></tr><tr><td data-num=\"9\"></td><td><pre><span class=\"token keyword\">int</span> <span class=\"token function\">main</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> </pre></td></tr><tr><td data-num=\"10\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"11\"></td><td><pre>    <span class=\"token keyword\">int</span> arr<span class=\"token punctuation\">[</span><span class=\"token number\">3</span><span class=\"token punctuation\">]</span> <span class=\"token operator\">=</span> <span class=\"token punctuation\">&#123;</span><span class=\"token number\">1</span><span class=\"token punctuation\">,</span> <span class=\"token number\">2</span><span class=\"token punctuation\">,</span> <span class=\"token number\">3</span><span class=\"token punctuation\">&#125;</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"12\"></td><td><pre>    <span class=\"token function\">getElement</span><span class=\"token punctuation\">(</span>arr<span class=\"token punctuation\">,</span> <span class=\"token number\">0</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=</span> <span class=\"token number\">4</span><span class=\"token punctuation\">;</span>  <span class=\"token comment\">// 通过引用修改数组元素</span></pre></td></tr><tr><td data-num=\"13\"></td><td><pre>    cout <span class=\"token operator\">&lt;&lt;</span> arr<span class=\"token punctuation\">[</span><span class=\"token number\">0</span><span class=\"token punctuation\">]</span> <span class=\"token operator\">&lt;&lt;</span> endl<span class=\"token punctuation\">;</span>  <span class=\"token comment\">// 输出 4</span></pre></td></tr><tr><td data-num=\"14\"></td><td><pre>    <span class=\"token keyword\">return</span> <span class=\"token number\">0</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"15\"></td><td><pre><span class=\"token punctuation\">&#125;</span></pre></td></tr></table></figure><p>那如果返回值是栈帧内开辟的局部变量会发生什么呢？且看下例：</p>\n<figure class=\"highlight cpp\"><figcaption data-lang=\"C++\"></figcaption><table><tr><td data-num=\"1\"></td><td><pre><span class=\"token keyword\">int</span><span class=\"token operator\">&amp;</span> <span class=\"token function\">Add</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">int</span> a<span class=\"token punctuation\">,</span> <span class=\"token keyword\">int</span> b<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"2\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"3\"></td><td><pre>    <span class=\"token keyword\">int</span> c <span class=\"token operator\">=</span> a <span class=\"token operator\">+</span> b<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"4\"></td><td><pre>    <span class=\"token keyword\">return</span> c<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"5\"></td><td><pre><span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"6\"></td><td><pre></pre></td></tr><tr><td data-num=\"7\"></td><td><pre><span class=\"token keyword\">int</span> <span class=\"token function\">main</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"8\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"9\"></td><td><pre>    <span class=\"token keyword\">int</span><span class=\"token operator\">&amp;</span> ret <span class=\"token operator\">=</span> <span class=\"token function\">Add</span><span class=\"token punctuation\">(</span><span class=\"token number\">1</span><span class=\"token punctuation\">,</span> <span class=\"token number\">2</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"10\"></td><td><pre>    <span class=\"token function\">Add</span><span class=\"token punctuation\">(</span><span class=\"token number\">3</span><span class=\"token punctuation\">,</span> <span class=\"token number\">4</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"11\"></td><td><pre>    cout <span class=\"token operator\">&lt;&lt;</span> <span class=\"token string\">\"Add(1,2) is: \"</span> <span class=\"token operator\">&lt;&lt;</span> ret <span class=\"token operator\">&lt;&lt;</span> endl<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"12\"></td><td><pre>    <span class=\"token keyword\">return</span> <span class=\"token number\">0</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"13\"></td><td><pre><span class=\"token punctuation\">&#125;</span></pre></td></tr></table></figure><p>其输出结果并非 3，而是 7，为什么呢？</p>\n<p>（现在不少编译器机制变的更加复杂，导致输出不是 7 而是一串随机值，但这只是一个例子）</p>\n<p>结合我们在<strong> C 语言笔记 #16</strong> 中的内容分析：</p>\n<p>第一次调用 Add 函数时，1 和 2 作为参数 ab 压栈，esp 寄存器上移。然后创建 Add 函数的栈帧，esp 和 ebp 移到 Add 函数的栈帧两端。变量 c 创建在 Add 函数栈帧中，而 Add 函数返回后 esp 和 ebp 回到 main 函数栈帧的两端，这片空间被释放。因此实际返回的是一片已经被释放的内存空间。</p>\n<p>但是此时如果直接输出，其仍能输出 3，因为虽然对应的空间已经被释放但是还没有被覆写。</p>\n<p>第二次调用 Add 函数时，3 与 4 压栈，esp 与 ebp 上移，创建 Add 函数的栈帧。此时除了数字不同，指令地址与第一次完全一致（较新的编译器可能不是了）。因此计算结果 7 放在了原本第一次 c 的位置，也就是把原本的 4 覆盖了。这时再去输出 ret 自然就得到了 Add (1, 2) = 7 的荒谬结论。</p>\n<h4 id=\"引用传值的优势\"><a class=\"anchor\" href=\"#引用传值的优势\">#</a> 引用传值的优势</h4>\n<p>避免数据的拷贝，当数据占空间较大时有很大的效率优势与空间优势。</p>\n<p>我们测试一下看看：</p>\n<figure class=\"highlight cpp\"><figcaption data-lang=\"C++\"></figcaption><table><tr><td data-num=\"1\"></td><td><pre><span class=\"token macro property\"><span class=\"token directive-hash\">#</span><span class=\"token directive keyword\">include</span> <span class=\"token string\">&lt;time.h></span></span></pre></td></tr><tr><td data-num=\"2\"></td><td><pre></pre></td></tr><tr><td data-num=\"3\"></td><td><pre><span class=\"token keyword\">struct</span> <span class=\"token class-name\">A</span></pre></td></tr><tr><td data-num=\"4\"></td><td><pre><span class=\"token punctuation\">&#123;</span> </pre></td></tr><tr><td data-num=\"5\"></td><td><pre>\t<span class=\"token keyword\">int</span> a<span class=\"token punctuation\">[</span><span class=\"token number\">10000</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">;</span> </pre></td></tr><tr><td data-num=\"6\"></td><td><pre><span class=\"token punctuation\">&#125;</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"7\"></td><td><pre></pre></td></tr><tr><td data-num=\"8\"></td><td><pre>A a<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"9\"></td><td><pre></pre></td></tr><tr><td data-num=\"10\"></td><td><pre>A <span class=\"token function\">TestFunc1</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">&#123;</span> <span class=\"token keyword\">return</span> a<span class=\"token punctuation\">;</span> <span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"11\"></td><td><pre>A<span class=\"token operator\">&amp;</span> <span class=\"token function\">TestFunc2</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">&#123;</span> <span class=\"token keyword\">return</span> a<span class=\"token punctuation\">;</span> <span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"12\"></td><td><pre></pre></td></tr><tr><td data-num=\"13\"></td><td><pre><span class=\"token keyword\">int</span> <span class=\"token function\">main</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"14\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"15\"></td><td><pre>\t<span class=\"token comment\">// 以值作为函数的返回值类型</span></pre></td></tr><tr><td data-num=\"16\"></td><td><pre>\tsize_t begin1 <span class=\"token operator\">=</span> <span class=\"token function\">clock</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"17\"></td><td><pre>\t<span class=\"token keyword\">for</span> <span class=\"token punctuation\">(</span>size_t i <span class=\"token operator\">=</span> <span class=\"token number\">0</span><span class=\"token punctuation\">;</span> i <span class=\"token operator\">&lt;</span> <span class=\"token number\">1000000</span><span class=\"token punctuation\">;</span> <span class=\"token operator\">++</span>i<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"18\"></td><td><pre>\t\t<span class=\"token function\">TestFunc1</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"19\"></td><td><pre>\tsize_t end1 <span class=\"token operator\">=</span> <span class=\"token function\">clock</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"20\"></td><td><pre>\t<span class=\"token comment\">// 以引用作为函数的返回值类型</span></pre></td></tr><tr><td data-num=\"21\"></td><td><pre>\tsize_t begin2 <span class=\"token operator\">=</span> <span class=\"token function\">clock</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"22\"></td><td><pre>\t<span class=\"token keyword\">for</span> <span class=\"token punctuation\">(</span>size_t i <span class=\"token operator\">=</span> <span class=\"token number\">0</span><span class=\"token punctuation\">;</span> i <span class=\"token operator\">&lt;</span> <span class=\"token number\">1000000</span><span class=\"token punctuation\">;</span> <span class=\"token operator\">++</span>i<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"23\"></td><td><pre>\t\t<span class=\"token function\">TestFunc2</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"24\"></td><td><pre>\tsize_t end2 <span class=\"token operator\">=</span> <span class=\"token function\">clock</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"25\"></td><td><pre>\t<span class=\"token comment\">// 计算两个函数运算完成之后的时间</span></pre></td></tr><tr><td data-num=\"26\"></td><td><pre>\tcout <span class=\"token operator\">&lt;&lt;</span> <span class=\"token string\">\"TestFunc1 time:\"</span> <span class=\"token operator\">&lt;&lt;</span> end1 <span class=\"token operator\">-</span> begin1 <span class=\"token operator\">&lt;&lt;</span> endl<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"27\"></td><td><pre>\tcout <span class=\"token operator\">&lt;&lt;</span> <span class=\"token string\">\"TestFunc2 time:\"</span> <span class=\"token operator\">&lt;&lt;</span> end2 <span class=\"token operator\">-</span> begin2 <span class=\"token operator\">&lt;&lt;</span> endl<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"28\"></td><td><pre></pre></td></tr><tr><td data-num=\"29\"></td><td><pre>\t<span class=\"token keyword\">return</span> <span class=\"token number\">0</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"30\"></td><td><pre><span class=\"token punctuation\">&#125;</span></pre></td></tr></table></figure><p>其输出：</p>\n<figure class=\"highlight bash\"><figcaption data-lang=\"bash\"></figcaption><table><tr><td data-num=\"1\"></td><td><pre>TestFunc1 time:1610</pre></td></tr><tr><td data-num=\"2\"></td><td><pre>TestFunc2 time:1</pre></td></tr></table></figure><p>可见其效率差距之大。</p>\n<h4 id=\"引用和指针的区别\"><a class=\"anchor\" href=\"#引用和指针的区别\">#</a> 引用和指针的区别</h4>\n<p>底层上引用就是靠指针实现的，优势在于可读性更高。</p>\n<p>我们把汇编对比一下就知道，指针实现和引用实现的汇编代码都是基本一致的。</p>\n<p>硬要说区别的话有如下几条：</p>\n<ol>\n<li>引用<strong>必须初始化</strong>，指针不需要。</li>\n<li>引用初始化后<strong>不能再引用其他实体</strong>了，指针的话只要是同类型的就能随便改。</li>\n<li>有空指针<strong>没有空引用</strong>。</li>\n<li><strong>sizeof 关键字对指针会得到地址所占的字节数，但是对引用能得到引用类型的大小。</strong></li>\n<li>引用自增自减作用于被引用实体，指针则作用于自身。</li>\n<li>存在多级指针，不存在多级引用。</li>\n<li>引用比指针更安全。</li>\n</ol>\n<h3 id=\"内联函数\"><a class=\"anchor\" href=\"#内联函数\">#</a> 内联函数</h3>\n<h4 id=\"内联函数的概念\"><a class=\"anchor\" href=\"#内联函数的概念\">#</a> 内联函数的概念</h4>\n<p>如果程序中有一个比较小的函数被频繁调用，我们就会面临这样的问题：这个函数<strong>太小了没什么必要去创建一个函数</strong>，这会造成很多没必要的栈帧开销；但是这个函数确实在程序中使用的很多，<strong>不写成函数而是拆开来写在程序里很麻烦</strong>。</p>\n<p>那么我们就可以使用<strong>内联函数</strong>解决这个问题；当然也可以使用<strong>宏或者宏函数</strong>解决，但是宏无法调试没有安全检查也非常容易出错，是<strong>不推荐使用</strong>的。</p>\n<p>在声明 / 定义函数的时候，在前面加上关键字 <code>inline</code> ，这个函数就会变成内联函数。</p>\n<p>编译器在处理内联函数时不会像正常函数一样写成调用函数的汇编代码，而是<strong>直接把这个内联函数在这里展开</strong>，比方说下面两段代码本质上没有区别：</p>\n<figure class=\"highlight cpp\"><figcaption data-lang=\"C++\"></figcaption><table><tr><td data-num=\"1\"></td><td><pre><span class=\"token keyword\">inline</span> <span class=\"token keyword\">int</span> <span class=\"token function\">max</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">int</span> a<span class=\"token punctuation\">,</span> <span class=\"token keyword\">int</span> b<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"2\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"3\"></td><td><pre>\t<span class=\"token keyword\">return</span> a <span class=\"token operator\">></span> b <span class=\"token operator\">?</span> a <span class=\"token operator\">:</span> b<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"4\"></td><td><pre><span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"5\"></td><td><pre></pre></td></tr><tr><td data-num=\"6\"></td><td><pre><span class=\"token keyword\">int</span> <span class=\"token function\">main</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"7\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"8\"></td><td><pre>\tcout <span class=\"token operator\">&lt;&lt;</span> <span class=\"token string\">\"max(10, 20) = \"</span> <span class=\"token operator\">&lt;&lt;</span> <span class=\"token function\">max</span><span class=\"token punctuation\">(</span><span class=\"token number\">10</span><span class=\"token punctuation\">,</span> <span class=\"token number\">20</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">&lt;&lt;</span> endl<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"9\"></td><td><pre>\tcout <span class=\"token operator\">&lt;&lt;</span> <span class=\"token string\">\"max(0, 0) = \"</span> <span class=\"token operator\">&lt;&lt;</span> <span class=\"token function\">max</span><span class=\"token punctuation\">(</span><span class=\"token number\">0</span><span class=\"token punctuation\">,</span> <span class=\"token number\">0</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">&lt;&lt;</span> endl<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"10\"></td><td><pre>\tcout <span class=\"token operator\">&lt;&lt;</span> <span class=\"token string\">\"max(-10, -20) = \"</span> <span class=\"token operator\">&lt;&lt;</span> <span class=\"token function\">max</span><span class=\"token punctuation\">(</span><span class=\"token operator\">-</span><span class=\"token number\">10</span><span class=\"token punctuation\">,</span> <span class=\"token operator\">-</span><span class=\"token number\">20</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">&lt;&lt;</span> endl<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"11\"></td><td><pre></pre></td></tr><tr><td data-num=\"12\"></td><td><pre>\t<span class=\"token keyword\">return</span> <span class=\"token number\">0</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"13\"></td><td><pre><span class=\"token punctuation\">&#125;</span></pre></td></tr></table></figure><figure class=\"highlight cpp\"><figcaption data-lang=\"C++\"></figcaption><table><tr><td data-num=\"1\"></td><td><pre><span class=\"token keyword\">int</span> <span class=\"token function\">main</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"2\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"3\"></td><td><pre>\tcout <span class=\"token operator\">&lt;&lt;</span> <span class=\"token string\">\"max(10, 20) = \"</span> <span class=\"token operator\">&lt;&lt;</span> <span class=\"token punctuation\">(</span><span class=\"token number\">10</span> <span class=\"token operator\">></span> <span class=\"token number\">20</span> <span class=\"token operator\">?</span> <span class=\"token number\">10</span> <span class=\"token operator\">:</span> <span class=\"token number\">20</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">&lt;&lt;</span> endl<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"4\"></td><td><pre>\tcout <span class=\"token operator\">&lt;&lt;</span> <span class=\"token string\">\"max(0, 0) = \"</span> <span class=\"token operator\">&lt;&lt;</span> <span class=\"token punctuation\">(</span><span class=\"token number\">0</span> <span class=\"token operator\">></span> <span class=\"token number\">0</span> <span class=\"token operator\">?</span> <span class=\"token number\">0</span> <span class=\"token operator\">:</span> <span class=\"token number\">0</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">&lt;&lt;</span> endl<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"5\"></td><td><pre>\tcout <span class=\"token operator\">&lt;&lt;</span> <span class=\"token string\">\"max(-10, -20) = \"</span> <span class=\"token operator\">&lt;&lt;</span> <span class=\"token punctuation\">(</span><span class=\"token operator\">-</span><span class=\"token number\">10</span> <span class=\"token operator\">></span> <span class=\"token operator\">-</span><span class=\"token number\">20</span> <span class=\"token operator\">?</span> <span class=\"token operator\">-</span><span class=\"token number\">10</span> <span class=\"token operator\">:</span> <span class=\"token operator\">-</span><span class=\"token number\">20</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">&lt;&lt;</span> endl<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"6\"></td><td><pre></pre></td></tr><tr><td data-num=\"7\"></td><td><pre>\t<span class=\"token keyword\">return</span> <span class=\"token number\">0</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"8\"></td><td><pre><span class=\"token punctuation\">&#125;</span></pre></td></tr></table></figure><h4 id=\"内联函数的意义\"><a class=\"anchor\" href=\"#内联函数的意义\">#</a> 内联函数的意义</h4>\n<p>内联函数是一种<mark>以时间换空间</mark>的做法，可能会让目标文件变的很大，但是能大大减少栈帧开销，提高运行效率。</p>\n<h4 id=\"内联函数的注意事项\"><a class=\"anchor\" href=\"#内联函数的注意事项\">#</a> 内联函数的注意事项</h4>\n<p><mark>注意：Visual Studio 中，在 debug 模式下，编译器一般不会对内联函数进行展开，需在 release 下进行。（或在编译器配置中设置内联函数扩展的属性）</mark></p>\n<p><mark>注意：内联函数只是向编译器提出了展开的建议，不同编译器对其实现机制可能不同。有可能写了内联编译器却不采纳，有可能没有写内联编译器却自己优化成了内联函数。</mark></p>\n<p><mark>注意：内联函数尽量不要声明与定义分离，因为编译器处理声明时找不到函数地址（内联函数直接展开没有函数地址），然后就会报链接错误或者直接忽略内联。</mark></p>\n<h3 id=\"auto关键字c11\"><a class=\"anchor\" href=\"#auto关键字c11\">#</a> auto 关键字（C++11）</h3>\n<h4 id=\"auto关键字的概念\"><a class=\"anchor\" href=\"#auto关键字的概念\">#</a> auto 关键字的概念</h4>\n<p>这里我们要说的是 C++11 开始的 auto 关键字，C++11 之前也有 auto 关键字，但是含义不同。</p>\n<p>auto 关键字在 C++11 之前用于在定义时<strong>修饰变量为具有自动存储期的变量</strong>，以表示这个变量会在离开当前作用域后自动归还内存。但是啊，我们如果没有单独去修饰变量为 static、extern 或 thread_local 的话，变量自然就会被创建为具有自动存储期的，正常人不会闲着没事干去加一个 auto 在前面。因此，auto 的这个用法在 C++11 以后已经废除。</p>\n<p>从 C++11 开始，<strong>auto 关键字用于替代类型名使用</strong>。什么意思呢？</p>\n<p>比方说<mark>我们定义各种类型的变量，都可以直接用 auto 来替代类型，编译器会自动分析这里应该是什么类型</mark>：</p>\n<figure class=\"highlight cpp\"><figcaption data-lang=\"C++\"></figcaption><table><tr><td data-num=\"1\"></td><td><pre><span class=\"token macro property\"><span class=\"token directive-hash\">#</span><span class=\"token directive keyword\">include</span> <span class=\"token string\">&lt;iostream></span></span></pre></td></tr><tr><td data-num=\"2\"></td><td><pre></pre></td></tr><tr><td data-num=\"3\"></td><td><pre><span class=\"token keyword\">using</span> <span class=\"token keyword\">namespace</span> std<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"4\"></td><td><pre></pre></td></tr><tr><td data-num=\"5\"></td><td><pre><span class=\"token keyword\">int</span> <span class=\"token function\">main</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"6\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"7\"></td><td><pre>\t<span class=\"token keyword\">auto</span> a <span class=\"token operator\">=</span> <span class=\"token number\">1</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"8\"></td><td><pre>\t<span class=\"token keyword\">auto</span> b <span class=\"token operator\">=</span> <span class=\"token number\">3.14</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"9\"></td><td><pre>\t<span class=\"token keyword\">auto</span> c <span class=\"token operator\">=</span> <span class=\"token punctuation\">&#123;</span> <span class=\"token number\">1</span><span class=\"token punctuation\">,</span> <span class=\"token number\">2</span> <span class=\"token punctuation\">&#125;</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"10\"></td><td><pre>\t<span class=\"token keyword\">auto</span> d <span class=\"token operator\">=</span> <span class=\"token string\">\"hello world\"</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"11\"></td><td><pre>\t<span class=\"token keyword\">auto</span> e <span class=\"token operator\">=</span> <span class=\"token char\">'c'</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"12\"></td><td><pre></pre></td></tr><tr><td data-num=\"13\"></td><td><pre>\tcout <span class=\"token operator\">&lt;&lt;</span> <span class=\"token keyword\">typeid</span><span class=\"token punctuation\">(</span>a<span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span><span class=\"token function\">name</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">&lt;&lt;</span> endl<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"14\"></td><td><pre>\tcout <span class=\"token operator\">&lt;&lt;</span> <span class=\"token keyword\">typeid</span><span class=\"token punctuation\">(</span>b<span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span><span class=\"token function\">name</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">&lt;&lt;</span> endl<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"15\"></td><td><pre>\tcout <span class=\"token operator\">&lt;&lt;</span> <span class=\"token keyword\">typeid</span><span class=\"token punctuation\">(</span>c<span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span><span class=\"token function\">name</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">&lt;&lt;</span> endl<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"16\"></td><td><pre>\tcout <span class=\"token operator\">&lt;&lt;</span> <span class=\"token keyword\">typeid</span><span class=\"token punctuation\">(</span>d<span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span><span class=\"token function\">name</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">&lt;&lt;</span> endl<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"17\"></td><td><pre>\tcout <span class=\"token operator\">&lt;&lt;</span> <span class=\"token keyword\">typeid</span><span class=\"token punctuation\">(</span>e<span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span><span class=\"token function\">name</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">&lt;&lt;</span> endl<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"18\"></td><td><pre></pre></td></tr><tr><td data-num=\"19\"></td><td><pre>\t<span class=\"token keyword\">return</span> <span class=\"token number\">0</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"20\"></td><td><pre><span class=\"token punctuation\">&#125;</span></pre></td></tr></table></figure><p>注意：这里的 <code>typeid().name()</code>  用于输出类型的名字。</p>\n<p>其输出结果为：</p>\n<figure class=\"highlight bash\"><figcaption data-lang=\"bash\"></figcaption><table><tr><td data-num=\"1\"></td><td><pre>int</pre></td></tr><tr><td data-num=\"2\"></td><td><pre>double</pre></td></tr><tr><td data-num=\"3\"></td><td><pre>class std::initializer_list<span class=\"token operator\">&lt;</span>int<span class=\"token operator\">></span></pre></td></tr><tr><td data-num=\"4\"></td><td><pre>char const * __ptr64</pre></td></tr><tr><td data-num=\"5\"></td><td><pre>char</pre></td></tr></table></figure><p><strong>又或者，我们可以在函数的返回值类型处写 auto，编译器同样会自动分析函数的返回值类型。</strong></p>\n<h4 id=\"auto关键字的注意事项\"><a class=\"anchor\" href=\"#auto关键字的注意事项\">#</a> auto 关键字的注意事项</h4>\n<p><mark>注意：在同一行用 auto 定义多个变量时，它们必须是相同类型的。</mark></p>\n<p><mark>注意：auto 声明指针类型时</mark> <code>*</code> <mark> 可加可不加，但是声明引用类型时，必须有</mark> <code>&amp;</code> 。</p>\n<p><mark>注意：auto 可以用于函数的返回值，但是不能用于函数的参数。</mark></p>\n<p>== 注意：auto 不要直接用于声明数组。== 像 <code>auto a[] = &#123;1, 2, 3&#125;;</code>  这种是非法的。</p>\n<h3 id=\"基于范围的for循环c11\"><a class=\"anchor\" href=\"#基于范围的for循环c11\">#</a> 基于范围的 for 循环（C++11）</h3>\n<p>在之前我们如果想遍历一个数组要这样做：</p>\n<figure class=\"highlight cpp\"><figcaption data-lang=\"C++\"></figcaption><table><tr><td data-num=\"1\"></td><td><pre><span class=\"token keyword\">void</span> <span class=\"token function\">TestForLoop</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"2\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"3\"></td><td><pre>\t<span class=\"token keyword\">int</span> arr<span class=\"token punctuation\">[</span><span class=\"token punctuation\">]</span> <span class=\"token operator\">=</span> <span class=\"token punctuation\">&#123;</span> <span class=\"token number\">1</span><span class=\"token punctuation\">,</span> <span class=\"token number\">2</span><span class=\"token punctuation\">,</span> <span class=\"token number\">3</span><span class=\"token punctuation\">,</span> <span class=\"token number\">4</span><span class=\"token punctuation\">,</span> <span class=\"token number\">5</span> <span class=\"token punctuation\">&#125;</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"4\"></td><td><pre>\t<span class=\"token keyword\">for</span> <span class=\"token punctuation\">(</span><span class=\"token keyword\">int</span> i <span class=\"token operator\">=</span> <span class=\"token number\">0</span><span class=\"token punctuation\">;</span> i <span class=\"token operator\">&lt;</span> <span class=\"token keyword\">sizeof</span><span class=\"token punctuation\">(</span>arr<span class=\"token punctuation\">)</span> <span class=\"token operator\">/</span> <span class=\"token keyword\">sizeof</span><span class=\"token punctuation\">(</span>arr<span class=\"token punctuation\">[</span><span class=\"token number\">0</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span> i<span class=\"token operator\">++</span><span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"5\"></td><td><pre>\t<span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"6\"></td><td><pre>\t\tarr<span class=\"token punctuation\">[</span>i<span class=\"token punctuation\">]</span> <span class=\"token operator\">*=</span> <span class=\"token number\">2</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"7\"></td><td><pre>\t<span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"8\"></td><td><pre>\t<span class=\"token keyword\">for</span> <span class=\"token punctuation\">(</span><span class=\"token keyword\">int</span> i <span class=\"token operator\">=</span> <span class=\"token number\">0</span><span class=\"token punctuation\">;</span> i <span class=\"token operator\">&lt;</span> <span class=\"token keyword\">sizeof</span><span class=\"token punctuation\">(</span>arr<span class=\"token punctuation\">)</span> <span class=\"token operator\">/</span> <span class=\"token keyword\">sizeof</span><span class=\"token punctuation\">(</span>arr<span class=\"token punctuation\">[</span><span class=\"token number\">0</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span> i<span class=\"token operator\">++</span><span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"9\"></td><td><pre>\t<span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"10\"></td><td><pre>\t\tcout <span class=\"token operator\">&lt;&lt;</span> arr<span class=\"token punctuation\">[</span>i<span class=\"token punctuation\">]</span> <span class=\"token operator\">&lt;&lt;</span> <span class=\"token string\">\" \"</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"11\"></td><td><pre>\t<span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"12\"></td><td><pre><span class=\"token punctuation\">&#125;</span></pre></td></tr></table></figure><p>而在 C++11 以后，可以直接写成：</p>\n<figure class=\"highlight cpp\"><figcaption data-lang=\"C++\"></figcaption><table><tr><td data-num=\"1\"></td><td><pre><span class=\"token keyword\">void</span> <span class=\"token function\">TestForLoopWithRange</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"2\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"3\"></td><td><pre>\t<span class=\"token keyword\">int</span> arr<span class=\"token punctuation\">[</span><span class=\"token punctuation\">]</span> <span class=\"token operator\">=</span> <span class=\"token punctuation\">&#123;</span> <span class=\"token number\">1</span><span class=\"token punctuation\">,</span> <span class=\"token number\">2</span><span class=\"token punctuation\">,</span> <span class=\"token number\">3</span><span class=\"token punctuation\">,</span> <span class=\"token number\">4</span><span class=\"token punctuation\">,</span> <span class=\"token number\">5</span> <span class=\"token punctuation\">&#125;</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"4\"></td><td><pre>\t<span class=\"token keyword\">for</span> <span class=\"token punctuation\">(</span><span class=\"token keyword\">auto</span><span class=\"token operator\">&amp;</span> e <span class=\"token operator\">:</span> arr<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"5\"></td><td><pre>\t<span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"6\"></td><td><pre>\t\te <span class=\"token operator\">*=</span> <span class=\"token number\">2</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"7\"></td><td><pre>\t<span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"8\"></td><td><pre>\t<span class=\"token keyword\">for</span> <span class=\"token punctuation\">(</span><span class=\"token keyword\">auto</span> e <span class=\"token operator\">:</span> arr<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"9\"></td><td><pre>\t<span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"10\"></td><td><pre>\t\tcout <span class=\"token operator\">&lt;&lt;</span> e <span class=\"token operator\">&lt;&lt;</span> <span class=\"token string\">\" \"</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"11\"></td><td><pre>\t<span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"12\"></td><td><pre><span class=\"token punctuation\">&#125;</span></pre></td></tr></table></figure><p>这里 for 循环的括号中有冒号分割为两个部分：</p>\n<ul>\n<li>左边是在某个范围内用于迭代的变量，一般用 auto 定义。如果要对范围本身的数据进行修改，就要向上面那样写成引用形式的变量。</li>\n<li>右边是迭代的范围，目前我们只能接触到数组，之后还有别的迭代器。</li>\n</ul>\n<p>指针空值 nullptr（C++11）</p>\n<p>在我们<mark>声明一个变量的时候，良好的习惯是在声明时进行初始化。如果声明一个指针而暂时没有指向，我们一般会将其初始化为空指针</mark>。</p>\n<p>在之前，我们空指针一般直接用 NULL 来赋值，比方说 <code>int* p = NULL;</code> 。</p>\n<p>NULL 实际上是一个宏，我们在 <code>stddef.h</code>  中能够看到其定义：</p>\n<figure class=\"highlight cpp\"><figcaption data-lang=\"C++\"></figcaption><table><tr><td data-num=\"1\"></td><td><pre><span class=\"token macro property\"><span class=\"token directive-hash\">#</span><span class=\"token directive keyword\">ifndef</span> <span class=\"token expression\"><span class=\"token constant\">NULL</span></span></span></pre></td></tr><tr><td data-num=\"2\"></td><td><pre><span class=\"token macro property\"><span class=\"token directive-hash\">#</span><span class=\"token directive keyword\">ifdef</span> <span class=\"token expression\">__cplusplus</span></span></pre></td></tr><tr><td data-num=\"3\"></td><td><pre><span class=\"token macro property\"><span class=\"token directive-hash\">#</span><span class=\"token directive keyword\">define</span> <span class=\"token macro-name\">NULL</span>\t<span class=\"token expression\"><span class=\"token number\">0</span></span></span></pre></td></tr><tr><td data-num=\"4\"></td><td><pre><span class=\"token macro property\"><span class=\"token directive-hash\">#</span><span class=\"token directive keyword\">else</span></span></pre></td></tr><tr><td data-num=\"5\"></td><td><pre><span class=\"token macro property\"><span class=\"token directive-hash\">#</span><span class=\"token directive keyword\">define</span> <span class=\"token macro-name\">NULL</span>\t<span class=\"token expression\"><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">void</span> <span class=\"token operator\">*</span><span class=\"token punctuation\">)</span><span class=\"token number\">0</span><span class=\"token punctuation\">)</span></span></span></pre></td></tr><tr><td data-num=\"6\"></td><td><pre><span class=\"token macro property\"><span class=\"token directive-hash\">#</span><span class=\"token directive keyword\">endif</span></span></pre></td></tr><tr><td data-num=\"7\"></td><td><pre><span class=\"token macro property\"><span class=\"token directive-hash\">#</span><span class=\"token directive keyword\">endif</span></span></pre></td></tr></table></figure><p>我们发现在 C++ 中，NULL 被定义为 0，这可能会带来一些问题，比方说下面这段代码：</p>\n<figure class=\"highlight cpp\"><figcaption data-lang=\"C++\"></figcaption><table><tr><td data-num=\"1\"></td><td><pre><span class=\"token keyword\">void</span> <span class=\"token function\">func</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">int</span> i<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"2\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"3\"></td><td><pre>    cout <span class=\"token operator\">&lt;&lt;</span> <span class=\"token string\">\"int\"</span> <span class=\"token operator\">&lt;&lt;</span> endl<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"4\"></td><td><pre><span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"5\"></td><td><pre></pre></td></tr><tr><td data-num=\"6\"></td><td><pre><span class=\"token keyword\">void</span> <span class=\"token function\">func</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">int</span><span class=\"token operator\">*</span> pi<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"7\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"8\"></td><td><pre>    cout <span class=\"token operator\">&lt;&lt;</span> <span class=\"token string\">\"int*\"</span> <span class=\"token operator\">&lt;&lt;</span> endl<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"9\"></td><td><pre><span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"10\"></td><td><pre></pre></td></tr><tr><td data-num=\"11\"></td><td><pre><span class=\"token keyword\">int</span> <span class=\"token function\">main</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"12\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"13\"></td><td><pre>    <span class=\"token function\">func</span><span class=\"token punctuation\">(</span><span class=\"token number\">0</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"14\"></td><td><pre>    <span class=\"token function\">func</span><span class=\"token punctuation\">(</span><span class=\"token constant\">NULL</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"15\"></td><td><pre><span class=\"token punctuation\">&#125;</span></pre></td></tr></table></figure><p>我们发现两行输出都是 int，这显然与我们的初衷相悖。</p>\n<p>在 C++11 以后，增加了关键字 nullptr，不需要包含头文件。</p>\n<p>nullptr 默认为 <code>((void*)0)</code> ，<strong>且存在到任意指针类型的隐式转换</strong>。</p>\n<p>我们平时使用这个关键字而不是 NULL 作为空指针就能解决上面的问题，能够提高代码的健壮性。</p>\n",
            "tags": [
                "计算机科学",
                "C++笔记",
                "C++"
            ]
        },
        {
            "id": "https://www.starlinglin.top/computer-science/data-structure-note/%E6%A4%8B%E9%B8%9F%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84%E7%AC%94%E8%AE%B0%20%EF%BC%8311%EF%BC%9A%E6%8E%92%E5%BA%8F%C2%B7%E4%B8%8B/",
            "url": "https://www.starlinglin.top/computer-science/data-structure-note/%E6%A4%8B%E9%B8%9F%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84%E7%AC%94%E8%AE%B0%20%EF%BC%8311%EF%BC%9A%E6%8E%92%E5%BA%8F%C2%B7%E4%B8%8B/",
            "title": "椋鸟数据结构笔记#11：排序·下",
            "date_published": "2024-04-23T13:42:31.000Z",
            "content_html": "<div class=\"note info\">\n<p>该系列为本人的学习笔记，主要由本人整理书写而成。部分内容来自教材、视频课程等，不能保证完全原创性。</p>\n</div>\n<p>萌新的学习笔记，写错了恳请斧正。</p>\n<h3 id=\"外排序外部排序\"><a class=\"anchor\" href=\"#外排序外部排序\">#</a> 外排序（外部排序）</h3>\n<p>当<strong>数据量非常庞大以至于无法全部写入内存</strong>时，我们应该怎么排序这些数据呢？</p>\n<p>这时，就要学会直接进行在外存中排序，也就是外部排序。</p>\n<p>外排序不是一种独立的排序算法，还是要依赖于之前的那些排序方式。</p>\n<p>其基本思想是这样的：</p>\n<ul>\n<li>将庞大的数据拆分为一个一个子文件，使得每一个子文件的数据量在内存排序可承受的范围内。</li>\n<li>将每一个文件进行正常的排序，可以选用之前学的任何排序方法。</li>\n<li>将排序好的文件再进行归并，最终合成为包含有序的所有数据的文件。</li>\n</ul>\n<p>看起来不是很复杂，但是归并部分还是很有东西的。下面我们逐步讲解：</p>\n<h4 id=\"文件拆分并排序\"><a class=\"anchor\" href=\"#文件拆分并排序\">#</a> 文件拆分并排序</h4>\n<p>这并不复杂，比方说我们将文件拆分为 splitCount 个：</p>\n<figure class=\"highlight c\"><figcaption data-lang=\"c\"></figcaption><table><tr><td data-num=\"1\"></td><td><pre><span class=\"token keyword\">void</span> <span class=\"token function\">FileSort</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">const</span> <span class=\"token keyword\">char</span><span class=\"token operator\">*</span> filename<span class=\"token punctuation\">,</span> <span class=\"token keyword\">int</span> splitCount<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"2\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"3\"></td><td><pre>\t<span class=\"token class-name\">clock_t</span> start <span class=\"token operator\">=</span> <span class=\"token function\">clock</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"4\"></td><td><pre></pre></td></tr><tr><td data-num=\"5\"></td><td><pre>\t<span class=\"token comment\">// 分割文件</span></pre></td></tr><tr><td data-num=\"6\"></td><td><pre>\tFILE<span class=\"token operator\">*</span> fp <span class=\"token operator\">=</span> <span class=\"token function\">fopen</span><span class=\"token punctuation\">(</span>filename<span class=\"token punctuation\">,</span> <span class=\"token string\">\"r\"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"7\"></td><td><pre>\t<span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>fp <span class=\"token operator\">==</span> <span class=\"token constant\">NULL</span><span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"8\"></td><td><pre>\t<span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"9\"></td><td><pre>\t\t<span class=\"token function\">perror</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"fail to open\"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"10\"></td><td><pre>\t\t<span class=\"token function\">exit</span><span class=\"token punctuation\">(</span>EXIT_FAILURE<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"11\"></td><td><pre>\t<span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"12\"></td><td><pre>\t<span class=\"token keyword\">int</span><span class=\"token operator\">*</span> num <span class=\"token operator\">=</span> <span class=\"token punctuation\">(</span><span class=\"token keyword\">int</span><span class=\"token operator\">*</span><span class=\"token punctuation\">)</span><span class=\"token function\">malloc</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">sizeof</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">int</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">*</span> N <span class=\"token operator\">/</span> splitCount<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\t<span class=\"token comment\">// 存放每个分割文件的数据</span></pre></td></tr><tr><td data-num=\"13\"></td><td><pre>\t<span class=\"token keyword\">int</span> iNum <span class=\"token operator\">=</span> <span class=\"token number\">0</span><span class=\"token punctuation\">;</span>\t<span class=\"token comment\">//num 数组的下标</span></pre></td></tr><tr><td data-num=\"14\"></td><td><pre>\t<span class=\"token keyword\">int</span> iFile <span class=\"token operator\">=</span> <span class=\"token number\">0</span><span class=\"token punctuation\">;</span>\t<span class=\"token comment\">// 分割文件的下标</span></pre></td></tr><tr><td data-num=\"15\"></td><td><pre>\t<span class=\"token keyword\">int</span> n <span class=\"token operator\">=</span> <span class=\"token number\">0</span><span class=\"token punctuation\">;</span>\t<span class=\"token comment\">// 读取的数据</span></pre></td></tr><tr><td data-num=\"16\"></td><td><pre>\t<span class=\"token keyword\">char</span> splitFileName<span class=\"token punctuation\">[</span><span class=\"token number\">50</span><span class=\"token punctuation\">]</span> <span class=\"token operator\">=</span> <span class=\"token punctuation\">&#123;</span> <span class=\"token number\">0</span> <span class=\"token punctuation\">&#125;</span><span class=\"token punctuation\">;</span>\t<span class=\"token comment\">// 分割文件名</span></pre></td></tr><tr><td data-num=\"17\"></td><td><pre>\t<span class=\"token keyword\">while</span> <span class=\"token punctuation\">(</span><span class=\"token function\">fscanf</span><span class=\"token punctuation\">(</span>fp<span class=\"token punctuation\">,</span> <span class=\"token string\">\"%d\"</span><span class=\"token punctuation\">,</span> <span class=\"token operator\">&amp;</span>n<span class=\"token punctuation\">)</span> <span class=\"token operator\">!=</span> <span class=\"token constant\">EOF</span><span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"18\"></td><td><pre>\t<span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"19\"></td><td><pre>\t\t<span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>iNum <span class=\"token operator\">&lt;</span> N <span class=\"token operator\">/</span> splitCount <span class=\"token operator\">-</span> <span class=\"token number\">1</span><span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"20\"></td><td><pre>\t\t<span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"21\"></td><td><pre>\t\t\tnum<span class=\"token punctuation\">[</span>iNum<span class=\"token operator\">++</span><span class=\"token punctuation\">]</span> <span class=\"token operator\">=</span> n<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"22\"></td><td><pre>\t\t<span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"23\"></td><td><pre>\t\t<span class=\"token keyword\">else</span></pre></td></tr><tr><td data-num=\"24\"></td><td><pre>\t\t<span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"25\"></td><td><pre>\t\t\tnum<span class=\"token punctuation\">[</span>iNum<span class=\"token punctuation\">]</span> <span class=\"token operator\">=</span> n<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"26\"></td><td><pre>\t\t\t<span class=\"token comment\">// 排序</span></pre></td></tr><tr><td data-num=\"27\"></td><td><pre>\t\t\t<span class=\"token function\">HeapSort</span><span class=\"token punctuation\">(</span>num<span class=\"token punctuation\">,</span> N <span class=\"token operator\">/</span> splitCount<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"28\"></td><td><pre>\t\t\t<span class=\"token comment\">// 写入文件</span></pre></td></tr><tr><td data-num=\"29\"></td><td><pre>\t\t\t<span class=\"token function\">sprintf</span><span class=\"token punctuation\">(</span>splitFileName<span class=\"token punctuation\">,</span> <span class=\"token string\">\"SubSort\\\\sort_split%d.txt\"</span><span class=\"token punctuation\">,</span> iFile<span class=\"token operator\">++</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"30\"></td><td><pre>\t\t\tFILE<span class=\"token operator\">*</span> splitFile <span class=\"token operator\">=</span> <span class=\"token function\">fopen</span><span class=\"token punctuation\">(</span>splitFileName<span class=\"token punctuation\">,</span> <span class=\"token string\">\"w\"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"31\"></td><td><pre>\t\t\t<span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>splitFile <span class=\"token operator\">==</span> <span class=\"token constant\">NULL</span><span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"32\"></td><td><pre>\t\t\t<span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"33\"></td><td><pre>\t\t\t\t<span class=\"token function\">perror</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"fail to open\"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"34\"></td><td><pre>\t\t\t\t<span class=\"token function\">exit</span><span class=\"token punctuation\">(</span>EXIT_FAILURE<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"35\"></td><td><pre>\t\t\t<span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"36\"></td><td><pre>\t\t\t<span class=\"token keyword\">for</span> <span class=\"token punctuation\">(</span><span class=\"token keyword\">int</span> i <span class=\"token operator\">=</span> <span class=\"token number\">0</span><span class=\"token punctuation\">;</span> i <span class=\"token operator\">&lt;</span> N <span class=\"token operator\">/</span> splitCount<span class=\"token punctuation\">;</span> i<span class=\"token operator\">++</span><span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"37\"></td><td><pre>\t\t\t<span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"38\"></td><td><pre>\t\t\t\t<span class=\"token function\">fprintf</span><span class=\"token punctuation\">(</span>splitFile<span class=\"token punctuation\">,</span> <span class=\"token string\">\"%d\\n\"</span><span class=\"token punctuation\">,</span> num<span class=\"token punctuation\">[</span>i<span class=\"token punctuation\">]</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"39\"></td><td><pre>\t\t\t<span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"40\"></td><td><pre>\t\t\t<span class=\"token function\">fclose</span><span class=\"token punctuation\">(</span>splitFile<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"41\"></td><td><pre>\t\t\t<span class=\"token function\">printf</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"已分割第%d个文件，总共需分割%d个文件。\\n\"</span><span class=\"token punctuation\">,</span> iFile<span class=\"token punctuation\">,</span> splitCount<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"42\"></td><td><pre>\t\t\tiNum <span class=\"token operator\">=</span> <span class=\"token number\">0</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"43\"></td><td><pre>\t\t<span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"44\"></td><td><pre>\t<span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"45\"></td><td><pre></pre></td></tr><tr><td data-num=\"46\"></td><td><pre>\t<span class=\"token comment\">// 归并文件</span></pre></td></tr><tr><td data-num=\"47\"></td><td><pre>    <span class=\"token comment\">// 这里插入归并文件的代码</span></pre></td></tr><tr><td data-num=\"48\"></td><td><pre></pre></td></tr><tr><td data-num=\"49\"></td><td><pre>\t<span class=\"token comment\">// 关闭文件</span></pre></td></tr><tr><td data-num=\"50\"></td><td><pre>\t<span class=\"token function\">fclose</span><span class=\"token punctuation\">(</span>fp<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"51\"></td><td><pre></pre></td></tr><tr><td data-num=\"52\"></td><td><pre>\t<span class=\"token class-name\">clock_t</span> end <span class=\"token operator\">=</span> <span class=\"token function\">clock</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"53\"></td><td><pre></pre></td></tr><tr><td data-num=\"54\"></td><td><pre>\t<span class=\"token function\">printf</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"排序完成，共%d个数据，分割为%d个文件，归并为1个文件。\\n\"</span><span class=\"token punctuation\">,</span> N<span class=\"token punctuation\">,</span> splitCount<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"55\"></td><td><pre>\t<span class=\"token function\">printf</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"耗时：%f秒。\\n\"</span><span class=\"token punctuation\">,</span> <span class=\"token punctuation\">(</span><span class=\"token keyword\">double</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">(</span>end <span class=\"token operator\">-</span> start<span class=\"token punctuation\">)</span> <span class=\"token operator\">/</span> CLOCKS_PER_SEC<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"56\"></td><td><pre><span class=\"token punctuation\">&#125;</span></pre></td></tr></table></figure><h4 id=\"归并文件\"><a class=\"anchor\" href=\"#归并文件\">#</a> 归并文件</h4>\n<p>这是重点也是最复杂的地方。</p>\n<h5 id=\"两个文件归并\"><a class=\"anchor\" href=\"#两个文件归并\">#</a> 两个文件归并</h5>\n<p>我们知道两个排序文件归并的方法：两边一起读取，一直对比两边读取的数，不断取小写入输出文件即可。</p>\n<figure class=\"highlight c\"><figcaption data-lang=\"c\"></figcaption><table><tr><td data-num=\"1\"></td><td><pre><span class=\"token keyword\">void</span> <span class=\"token function\">MergeFile</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">char</span><span class=\"token operator\">*</span> file1<span class=\"token punctuation\">,</span> <span class=\"token keyword\">char</span><span class=\"token operator\">*</span> file2<span class=\"token punctuation\">,</span> <span class=\"token keyword\">char</span><span class=\"token operator\">*</span> mergeFileName<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"2\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"3\"></td><td><pre>\tFILE<span class=\"token operator\">*</span> fp1 <span class=\"token operator\">=</span> <span class=\"token function\">fopen</span><span class=\"token punctuation\">(</span>file1<span class=\"token punctuation\">,</span> <span class=\"token string\">\"r\"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"4\"></td><td><pre>\tFILE<span class=\"token operator\">*</span> fp2 <span class=\"token operator\">=</span> <span class=\"token function\">fopen</span><span class=\"token punctuation\">(</span>file2<span class=\"token punctuation\">,</span> <span class=\"token string\">\"r\"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"5\"></td><td><pre>\t<span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>fp1 <span class=\"token operator\">==</span> <span class=\"token constant\">NULL</span><span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"6\"></td><td><pre>\t<span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"7\"></td><td><pre>\t\t<span class=\"token function\">perror</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"fail to open\"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"8\"></td><td><pre>\t\t<span class=\"token function\">exit</span><span class=\"token punctuation\">(</span>EXIT_FAILURE<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"9\"></td><td><pre>\t<span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"10\"></td><td><pre>\t<span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>fp2 <span class=\"token operator\">==</span> <span class=\"token constant\">NULL</span><span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"11\"></td><td><pre>\t<span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"12\"></td><td><pre>\t\t<span class=\"token function\">perror</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"fail to open\"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"13\"></td><td><pre>\t\t<span class=\"token function\">exit</span><span class=\"token punctuation\">(</span>EXIT_FAILURE<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"14\"></td><td><pre>\t<span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"15\"></td><td><pre>\tFILE<span class=\"token operator\">*</span> fin <span class=\"token operator\">=</span> <span class=\"token function\">fopen</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"tmp.txt\"</span><span class=\"token punctuation\">,</span> <span class=\"token string\">\"w\"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"16\"></td><td><pre>\t<span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>fin <span class=\"token operator\">==</span> <span class=\"token constant\">NULL</span><span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"17\"></td><td><pre>\t<span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"18\"></td><td><pre>\t\t<span class=\"token function\">perror</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"fail to open\"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"19\"></td><td><pre>\t\t<span class=\"token function\">exit</span><span class=\"token punctuation\">(</span>EXIT_FAILURE<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"20\"></td><td><pre>\t<span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"21\"></td><td><pre>\t<span class=\"token keyword\">int</span> n1<span class=\"token punctuation\">,</span> n2<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"22\"></td><td><pre>\t<span class=\"token keyword\">int</span> ret1 <span class=\"token operator\">=</span> <span class=\"token function\">fscanf</span><span class=\"token punctuation\">(</span>fp1<span class=\"token punctuation\">,</span> <span class=\"token string\">\"%d\"</span><span class=\"token punctuation\">,</span> <span class=\"token operator\">&amp;</span>n1<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"23\"></td><td><pre>\t<span class=\"token keyword\">int</span> ret2 <span class=\"token operator\">=</span> <span class=\"token function\">fscanf</span><span class=\"token punctuation\">(</span>fp2<span class=\"token punctuation\">,</span> <span class=\"token string\">\"%d\"</span><span class=\"token punctuation\">,</span> <span class=\"token operator\">&amp;</span>n2<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"24\"></td><td><pre>\t<span class=\"token keyword\">while</span> <span class=\"token punctuation\">(</span>ret1 <span class=\"token operator\">!=</span> <span class=\"token constant\">EOF</span> <span class=\"token operator\">&amp;&amp;</span> ret2 <span class=\"token operator\">!=</span> <span class=\"token constant\">EOF</span><span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"25\"></td><td><pre>\t<span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"26\"></td><td><pre>\t\t<span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>n1 <span class=\"token operator\">&lt;</span> n2<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"27\"></td><td><pre>\t\t<span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"28\"></td><td><pre>\t\t\t<span class=\"token function\">fprintf</span><span class=\"token punctuation\">(</span>fin<span class=\"token punctuation\">,</span> <span class=\"token string\">\"%d\\n\"</span><span class=\"token punctuation\">,</span> n1<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"29\"></td><td><pre>\t\t\tret1 <span class=\"token operator\">=</span> <span class=\"token function\">fscanf</span><span class=\"token punctuation\">(</span>fp1<span class=\"token punctuation\">,</span> <span class=\"token string\">\"%d\"</span><span class=\"token punctuation\">,</span> <span class=\"token operator\">&amp;</span>n1<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"30\"></td><td><pre>\t\t<span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"31\"></td><td><pre>\t\t<span class=\"token keyword\">else</span></pre></td></tr><tr><td data-num=\"32\"></td><td><pre>\t\t<span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"33\"></td><td><pre>\t\t\t<span class=\"token function\">fprintf</span><span class=\"token punctuation\">(</span>fin<span class=\"token punctuation\">,</span> <span class=\"token string\">\"%d\\n\"</span><span class=\"token punctuation\">,</span> n2<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"34\"></td><td><pre>\t\t\tret2 <span class=\"token operator\">=</span> <span class=\"token function\">fscanf</span><span class=\"token punctuation\">(</span>fp2<span class=\"token punctuation\">,</span> <span class=\"token string\">\"%d\"</span><span class=\"token punctuation\">,</span> <span class=\"token operator\">&amp;</span>n2<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"35\"></td><td><pre>\t\t<span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"36\"></td><td><pre>\t<span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"37\"></td><td><pre>\t<span class=\"token keyword\">while</span> <span class=\"token punctuation\">(</span><span class=\"token function\">fscanf</span><span class=\"token punctuation\">(</span>fp1<span class=\"token punctuation\">,</span> <span class=\"token string\">\"%d\"</span><span class=\"token punctuation\">,</span> <span class=\"token operator\">&amp;</span>n1<span class=\"token punctuation\">)</span> <span class=\"token operator\">!=</span> <span class=\"token constant\">EOF</span><span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"38\"></td><td><pre>\t<span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"39\"></td><td><pre>\t\t<span class=\"token function\">fprintf</span><span class=\"token punctuation\">(</span>fin<span class=\"token punctuation\">,</span> <span class=\"token string\">\"%d\\n\"</span><span class=\"token punctuation\">,</span> n1<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"40\"></td><td><pre>\t<span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"41\"></td><td><pre>\t<span class=\"token keyword\">while</span> <span class=\"token punctuation\">(</span><span class=\"token function\">fscanf</span><span class=\"token punctuation\">(</span>fp2<span class=\"token punctuation\">,</span> <span class=\"token string\">\"%d\"</span><span class=\"token punctuation\">,</span> <span class=\"token operator\">&amp;</span>n2<span class=\"token punctuation\">)</span> <span class=\"token operator\">!=</span> <span class=\"token constant\">EOF</span><span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"42\"></td><td><pre>\t<span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"43\"></td><td><pre>\t\t<span class=\"token function\">fprintf</span><span class=\"token punctuation\">(</span>fin<span class=\"token punctuation\">,</span> <span class=\"token string\">\"%d\\n\"</span><span class=\"token punctuation\">,</span> n2<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"44\"></td><td><pre>\t<span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"45\"></td><td><pre>\t<span class=\"token function\">fclose</span><span class=\"token punctuation\">(</span>fp1<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"46\"></td><td><pre>\t<span class=\"token function\">fclose</span><span class=\"token punctuation\">(</span>fp2<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"47\"></td><td><pre>\t<span class=\"token function\">fclose</span><span class=\"token punctuation\">(</span>fin<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"48\"></td><td><pre>\t<span class=\"token function\">remove</span><span class=\"token punctuation\">(</span>file1<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"49\"></td><td><pre>\t<span class=\"token function\">remove</span><span class=\"token punctuation\">(</span>file2<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"50\"></td><td><pre>\t<span class=\"token function\">rename</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"tmp.txt\"</span><span class=\"token punctuation\">,</span> mergeFileName<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"51\"></td><td><pre><span class=\"token punctuation\">&#125;</span></pre></td></tr></table></figure><p><mark>注意：这里我们先写入数据至 tmp.txt 中，最后在将其改名为 mergeFileName 是为了防止 mergeFileName 就是 file1 或者 file2 的情况（也即直接把 file2 归并到 file1 中而不创建新的文件，或者反过来）。</mark></p>\n<h5 id=\"多文件归并\"><a class=\"anchor\" href=\"#多文件归并\">#</a> 多文件归并</h5>\n<p>但是我们往往不仅仅要把数据切分为两个，而是几十个上百个。这时我们就需要使用多文件归并的方法。</p>\n<ol>\n<li>\n<p>直接逐个归并</p>\n<p>这是最容易理解也是最差的方法。就是把拆分文件 1 和拆分文件 2 归并，结果再和拆分文件 3 归并，结果再和拆分文件 4 归并…… 最终得到完整的归并文件。</p>\n<p>傻子都能看出来这个方法的不靠谱，但是我们还是将代码贴出来：</p>\n<figure class=\"highlight c\"><figcaption data-lang=\"c\"></figcaption><table><tr><td data-num=\"1\"></td><td><pre><span class=\"token comment\">// 归并文件，这段代码填入上方 FileSort 函数中归并的留空位置</span></pre></td></tr><tr><td data-num=\"2\"></td><td><pre><span class=\"token keyword\">char</span><span class=\"token operator\">*</span> mergeFileName <span class=\"token operator\">=</span> <span class=\"token string\">\"sort_merge.txt\"</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"3\"></td><td><pre><span class=\"token keyword\">char</span> file1<span class=\"token punctuation\">[</span><span class=\"token number\">50</span><span class=\"token punctuation\">]</span> <span class=\"token operator\">=</span> <span class=\"token string\">\"SubSort\\\\sort_split0.txt\"</span><span class=\"token punctuation\">,</span> file2<span class=\"token punctuation\">[</span><span class=\"token number\">50</span><span class=\"token punctuation\">]</span> <span class=\"token operator\">=</span> <span class=\"token punctuation\">&#123;</span><span class=\"token number\">0</span><span class=\"token punctuation\">&#125;</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"4\"></td><td><pre><span class=\"token keyword\">for</span> <span class=\"token punctuation\">(</span><span class=\"token keyword\">int</span> i <span class=\"token operator\">=</span> <span class=\"token number\">1</span><span class=\"token punctuation\">;</span> i <span class=\"token operator\">&lt;</span> splitCount<span class=\"token punctuation\">;</span> i<span class=\"token operator\">++</span><span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"5\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"6\"></td><td><pre>\t<span class=\"token function\">sprintf</span><span class=\"token punctuation\">(</span>file2<span class=\"token punctuation\">,</span> <span class=\"token string\">\"SubSort\\\\sort_split%d.txt\"</span><span class=\"token punctuation\">,</span> i<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"7\"></td><td><pre>\t<span class=\"token function\">MergeFile</span><span class=\"token punctuation\">(</span>file1<span class=\"token punctuation\">,</span> file2<span class=\"token punctuation\">,</span> mergeFileName<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"8\"></td><td><pre>\t<span class=\"token function\">strcpy</span><span class=\"token punctuation\">(</span>file1<span class=\"token punctuation\">,</span> mergeFileName<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"9\"></td><td><pre>\t<span class=\"token function\">printf</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"已归并%d个文件，总共需归并%d个文件。\\n\"</span><span class=\"token punctuation\">,</span> i <span class=\"token operator\">+</span> <span class=\"token number\">1</span><span class=\"token punctuation\">,</span> splitCount<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"10\"></td><td><pre><span class=\"token punctuation\">&#125;</span></pre></td></tr></table></figure><p>这个方法是真的不靠谱，一亿个数据半小时还没归并完。</p>\n</li>\n<li>\n<p>分治归并</p>\n<p>就是不断地两两分组归并，比方说 9 至 16 个文件归并成 5 至 8 个，5 至 8 个归并位 3 至 4 个，再归并为 2 个，最后合成完整的排序后文件。</p>\n<figure class=\"highlight c\"><figcaption data-lang=\"c\"></figcaption><table><tr><td data-num=\"1\"></td><td><pre><span class=\"token comment\">// 分治归并文件，这段代码填入上方 FileSort 函数中归并的留空位置</span></pre></td></tr><tr><td data-num=\"2\"></td><td><pre><span class=\"token function\">MergeFileR</span><span class=\"token punctuation\">(</span><span class=\"token number\">0</span><span class=\"token punctuation\">,</span> splitCount <span class=\"token operator\">-</span> <span class=\"token number\">1</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"3\"></td><td><pre><span class=\"token function\">remove</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"SubSort\\\\sort_split0.txt\"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr></table></figure><p>其中 MergeFileR 的定义如下：</p>\n<figure class=\"highlight c\"><figcaption data-lang=\"c\"></figcaption><table><tr><td data-num=\"1\"></td><td><pre><span class=\"token keyword\">void</span> <span class=\"token function\">MergeFileR</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">int</span> left<span class=\"token punctuation\">,</span> <span class=\"token keyword\">int</span> right<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"2\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"3\"></td><td><pre>\t<span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>left <span class=\"token operator\">>=</span> right<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"4\"></td><td><pre>\t<span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"5\"></td><td><pre>\t\t<span class=\"token keyword\">return</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"6\"></td><td><pre>\t<span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"7\"></td><td><pre>\t<span class=\"token keyword\">int</span> mid <span class=\"token operator\">=</span> <span class=\"token punctuation\">(</span>left <span class=\"token operator\">+</span> right<span class=\"token punctuation\">)</span> <span class=\"token operator\">/</span> <span class=\"token number\">2</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"8\"></td><td><pre>\t<span class=\"token comment\">// 递归归并</span></pre></td></tr><tr><td data-num=\"9\"></td><td><pre>\t<span class=\"token function\">MergeFileR</span><span class=\"token punctuation\">(</span>left<span class=\"token punctuation\">,</span> mid<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"10\"></td><td><pre>\t<span class=\"token function\">MergeFileR</span><span class=\"token punctuation\">(</span>mid <span class=\"token operator\">+</span> <span class=\"token number\">1</span><span class=\"token punctuation\">,</span> right<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"11\"></td><td><pre>\t<span class=\"token comment\">// 归并</span></pre></td></tr><tr><td data-num=\"12\"></td><td><pre>\t<span class=\"token keyword\">char</span> file1<span class=\"token punctuation\">[</span><span class=\"token number\">50</span><span class=\"token punctuation\">]</span> <span class=\"token operator\">=</span> <span class=\"token punctuation\">&#123;</span> <span class=\"token number\">0</span> <span class=\"token punctuation\">&#125;</span><span class=\"token punctuation\">,</span> file2<span class=\"token punctuation\">[</span><span class=\"token number\">50</span><span class=\"token punctuation\">]</span> <span class=\"token operator\">=</span> <span class=\"token punctuation\">&#123;</span> <span class=\"token number\">0</span> <span class=\"token punctuation\">&#125;</span><span class=\"token punctuation\">,</span> mergeFileName<span class=\"token punctuation\">[</span><span class=\"token number\">50</span><span class=\"token punctuation\">]</span> <span class=\"token operator\">=</span> <span class=\"token punctuation\">&#123;</span> <span class=\"token number\">0</span> <span class=\"token punctuation\">&#125;</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"13\"></td><td><pre>\t<span class=\"token function\">sprintf</span><span class=\"token punctuation\">(</span>file1<span class=\"token punctuation\">,</span> <span class=\"token string\">\"SubSort\\\\sort_split%d.txt\"</span><span class=\"token punctuation\">,</span> left<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"14\"></td><td><pre>\t<span class=\"token function\">sprintf</span><span class=\"token punctuation\">(</span>file2<span class=\"token punctuation\">,</span> <span class=\"token string\">\"SubSort\\\\sort_split%d.txt\"</span><span class=\"token punctuation\">,</span> mid <span class=\"token operator\">+</span> <span class=\"token number\">1</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"15\"></td><td><pre>\t<span class=\"token function\">sprintf</span><span class=\"token punctuation\">(</span>mergeFileName<span class=\"token punctuation\">,</span> <span class=\"token string\">\"SubSort\\\\sort_split%d.txt\"</span><span class=\"token punctuation\">,</span> left<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"16\"></td><td><pre>\t<span class=\"token function\">MergeFile</span><span class=\"token punctuation\">(</span>file1<span class=\"token punctuation\">,</span> file2<span class=\"token punctuation\">,</span> mergeFileName<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"17\"></td><td><pre>\t<span class=\"token function\">printf</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"已归并%d与%d文件至%d。\\n\"</span><span class=\"token punctuation\">,</span> left<span class=\"token punctuation\">,</span> mid <span class=\"token operator\">+</span> <span class=\"token number\">1</span><span class=\"token punctuation\">,</span> left<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"18\"></td><td><pre><span class=\"token punctuation\">&#125;</span></pre></td></tr></table></figure><p>这个方法要靠谱一点，测试如下：</p>\n<p><img data-src=\"test.png\" alt=\"测试\" /></p>\n</li>\n</ol>\n<h5 id=\"优化\"><a class=\"anchor\" href=\"#优化\">#</a> 优化</h5>\n<p>进一步优化可以将基础操作从两个文件归并变成 3 个文件归并或者更多，这样分治时就是 3 合一或者更多。这样多路归并会增加内存开销和内部时间开销，但是会大大减少外部读写的开销。</p>\n<p>更进一步优化可以引入败者树、最佳归并树等，我还不会。</p>\n",
            "tags": [
                "计算机科学",
                "数据结构笔记",
                "算法",
                "数据结构",
                "排序"
            ]
        },
        {
            "id": "https://www.starlinglin.top/computer-science/data-structure-note/%E6%A4%8B%E9%B8%9F%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84%E7%AC%94%E8%AE%B0%20%EF%BC%8310%EF%BC%9A%E6%8E%92%E5%BA%8F%C2%B7%E4%B8%AD/",
            "url": "https://www.starlinglin.top/computer-science/data-structure-note/%E6%A4%8B%E9%B8%9F%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84%E7%AC%94%E8%AE%B0%20%EF%BC%8310%EF%BC%9A%E6%8E%92%E5%BA%8F%C2%B7%E4%B8%AD/",
            "title": "椋鸟数据结构笔记#10：排序·中",
            "date_published": "2024-04-20T12:45:25.000Z",
            "content_html": "<div class=\"note info\">\n<p>该系列为本人的学习笔记，主要由本人整理书写而成。部分内容来自教材、视频课程等，不能保证完全原创性。</p>\n</div>\n<p>萌新的学习笔记，写错了恳请斧正。</p>\n<h3 id=\"四-归并排序\"><a class=\"anchor\" href=\"#四-归并排序\">#</a> 四、归并排序</h3>\n<p><img data-src=\"%E5%BD%92%E5%B9%B6%E6%8E%92%E5%BA%8F.gif\" alt=\"归并排序\" /></p>\n<p>归并排序是一种非常高效的排序算法。基本思想是将一个大数组分成两半，分别对这两半进行排序，然后将排序好的两部分合并在一起。这个过程递归进行，每次将数组分半，直到每个部分只有一个元素，自然是有序的，最终得到一个完整的有序数组。</p>\n<p>归并排序的步骤如下：</p>\n<ol>\n<li><strong>分割</strong>：把当前序列平均分割成两半。</li>\n<li><strong>递归排序</strong>：递归地对这两半进行归并排序，直到分割的子序列只包含一个元素。</li>\n<li><strong>合并</strong>：将两个有序的子序列合并成一个有序序列。</li>\n</ol>\n<h5 id=\"时间复杂度\"><a class=\"anchor\" href=\"#时间复杂度\">#</a> 时间复杂度</h5>\n<p>归并排序的时间复杂度为<span class=\"katex\"><span class=\"katex-mathml\"><math xmlns=\"http://www.w3.org/1998/Math/MathML\"><semantics><mrow><mi>O</mi><mo stretchy=\"false\">(</mo><mi>N</mi><mi>log</mi><mo>⁡</mo><mtext> </mtext><mi>N</mi><mo stretchy=\"false\">)</mo></mrow><annotation encoding=\"application/x-tex\">O(N\\log\\,N)</annotation></semantics></math></span><span class=\"katex-html\" aria-hidden=\"true\"><span class=\"base\"><span class=\"strut\" style=\"height:1em;vertical-align:-0.25em;\"></span><span class=\"mord mathnormal\" style=\"margin-right:0.02778em;\">O</span><span class=\"mopen\">(</span><span class=\"mord mathnormal\" style=\"margin-right:0.10903em;\">N</span><span class=\"mspace\" style=\"margin-right:0.16666666666666666em;\"></span><span class=\"mop\">lo<span style=\"margin-right:0.01389em;\">g</span></span><span class=\"mspace\" style=\"margin-right:0.16666666666666666em;\"></span><span class=\"mspace\" style=\"margin-right:0.16666666666666666em;\"></span><span class=\"mord mathnormal\" style=\"margin-right:0.10903em;\">N</span><span class=\"mclose\">)</span></span></span></span>​，<mark>在最好最坏情况都是如此</mark>。是一种效率稳定的排序方法。</p>\n<h5 id=\"实现\"><a class=\"anchor\" href=\"#实现\">#</a> 实现</h5>\n<h6 id=\"递归实现\"><a class=\"anchor\" href=\"#递归实现\">#</a> 递归实现</h6>\n<figure class=\"highlight c\"><figcaption data-lang=\"c\"><span>归并排序 递归</span></figcaption><table><tr><td data-num=\"1\"></td><td><pre><span class=\"token keyword\">void</span> <span class=\"token function\">_MergeSort</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">int</span><span class=\"token operator\">*</span> arr<span class=\"token punctuation\">,</span> <span class=\"token keyword\">int</span> left<span class=\"token punctuation\">,</span> <span class=\"token keyword\">int</span> right<span class=\"token punctuation\">,</span> <span class=\"token keyword\">int</span><span class=\"token operator\">*</span> tmp<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"2\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"3\"></td><td><pre>\t<span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>left <span class=\"token operator\">>=</span> right<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"4\"></td><td><pre>\t<span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"5\"></td><td><pre>\t\t<span class=\"token keyword\">return</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"6\"></td><td><pre>\t<span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"7\"></td><td><pre></pre></td></tr><tr><td data-num=\"8\"></td><td><pre>\t<span class=\"token keyword\">int</span> mid <span class=\"token operator\">=</span> <span class=\"token punctuation\">(</span>left <span class=\"token operator\">+</span> right<span class=\"token punctuation\">)</span> <span class=\"token operator\">/</span> <span class=\"token number\">2</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"9\"></td><td><pre>\t<span class=\"token comment\">//[left, mid] [mid + 1, right]</span></pre></td></tr><tr><td data-num=\"10\"></td><td><pre>\t</pre></td></tr><tr><td data-num=\"11\"></td><td><pre>\t<span class=\"token function\">_MergeSort</span><span class=\"token punctuation\">(</span>arr<span class=\"token punctuation\">,</span> left<span class=\"token punctuation\">,</span> mid<span class=\"token punctuation\">,</span> tmp<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"12\"></td><td><pre>\t<span class=\"token function\">_MergeSort</span><span class=\"token punctuation\">(</span>arr<span class=\"token punctuation\">,</span> mid <span class=\"token operator\">+</span> <span class=\"token number\">1</span><span class=\"token punctuation\">,</span> right<span class=\"token punctuation\">,</span> tmp<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"13\"></td><td><pre></pre></td></tr><tr><td data-num=\"14\"></td><td><pre>\t<span class=\"token comment\">// 合并</span></pre></td></tr><tr><td data-num=\"15\"></td><td><pre>\t<span class=\"token keyword\">int</span> begin1 <span class=\"token operator\">=</span> left<span class=\"token punctuation\">,</span> end1 <span class=\"token operator\">=</span> mid<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"16\"></td><td><pre>\t<span class=\"token keyword\">int</span> begin2 <span class=\"token operator\">=</span> mid <span class=\"token operator\">+</span> <span class=\"token number\">1</span><span class=\"token punctuation\">,</span> end2 <span class=\"token operator\">=</span> right<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"17\"></td><td><pre>\t<span class=\"token keyword\">int</span> index <span class=\"token operator\">=</span> left<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"18\"></td><td><pre>\t<span class=\"token keyword\">while</span> <span class=\"token punctuation\">(</span>begin1 <span class=\"token operator\">&lt;=</span> end1 <span class=\"token operator\">&amp;&amp;</span> begin2 <span class=\"token operator\">&lt;=</span> end2<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"19\"></td><td><pre>\t<span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"20\"></td><td><pre>\t\t<span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>arr<span class=\"token punctuation\">[</span>begin1<span class=\"token punctuation\">]</span> <span class=\"token operator\">&lt;</span> arr<span class=\"token punctuation\">[</span>begin2<span class=\"token punctuation\">]</span><span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"21\"></td><td><pre>\t\t<span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"22\"></td><td><pre>\t\t\ttmp<span class=\"token punctuation\">[</span>index<span class=\"token operator\">++</span><span class=\"token punctuation\">]</span> <span class=\"token operator\">=</span> arr<span class=\"token punctuation\">[</span>begin1<span class=\"token operator\">++</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"23\"></td><td><pre>\t\t<span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"24\"></td><td><pre>\t\t<span class=\"token keyword\">else</span></pre></td></tr><tr><td data-num=\"25\"></td><td><pre>\t\t<span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"26\"></td><td><pre>\t\t\ttmp<span class=\"token punctuation\">[</span>index<span class=\"token operator\">++</span><span class=\"token punctuation\">]</span> <span class=\"token operator\">=</span> arr<span class=\"token punctuation\">[</span>begin2<span class=\"token operator\">++</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"27\"></td><td><pre>\t\t<span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"28\"></td><td><pre>\t<span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"29\"></td><td><pre>\t<span class=\"token keyword\">while</span> <span class=\"token punctuation\">(</span>begin1 <span class=\"token operator\">&lt;=</span> end1<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"30\"></td><td><pre>\t<span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"31\"></td><td><pre>\t\ttmp<span class=\"token punctuation\">[</span>index<span class=\"token operator\">++</span><span class=\"token punctuation\">]</span> <span class=\"token operator\">=</span> arr<span class=\"token punctuation\">[</span>begin1<span class=\"token operator\">++</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"32\"></td><td><pre>\t<span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"33\"></td><td><pre>\t<span class=\"token keyword\">while</span> <span class=\"token punctuation\">(</span>begin2 <span class=\"token operator\">&lt;=</span> end2<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"34\"></td><td><pre>\t<span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"35\"></td><td><pre>\t\ttmp<span class=\"token punctuation\">[</span>index<span class=\"token operator\">++</span><span class=\"token punctuation\">]</span> <span class=\"token operator\">=</span> arr<span class=\"token punctuation\">[</span>begin2<span class=\"token operator\">++</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"36\"></td><td><pre>\t<span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"37\"></td><td><pre>\t<span class=\"token function\">memcpy</span><span class=\"token punctuation\">(</span>arr <span class=\"token operator\">+</span> left<span class=\"token punctuation\">,</span> tmp <span class=\"token operator\">+</span> left<span class=\"token punctuation\">,</span> <span class=\"token keyword\">sizeof</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">int</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">*</span> <span class=\"token punctuation\">(</span>right <span class=\"token operator\">-</span> left <span class=\"token operator\">+</span> <span class=\"token number\">1</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"38\"></td><td><pre><span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"39\"></td><td><pre></pre></td></tr><tr><td data-num=\"40\"></td><td><pre><span class=\"token keyword\">void</span> <span class=\"token function\">MergeSort</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">int</span><span class=\"token operator\">*</span> arr<span class=\"token punctuation\">,</span> <span class=\"token keyword\">int</span> n<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"41\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"42\"></td><td><pre>\t<span class=\"token keyword\">int</span><span class=\"token operator\">*</span> tmp <span class=\"token operator\">=</span> <span class=\"token punctuation\">(</span><span class=\"token keyword\">int</span><span class=\"token operator\">*</span><span class=\"token punctuation\">)</span><span class=\"token function\">malloc</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">sizeof</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">int</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">*</span> n<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"43\"></td><td><pre>\t<span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>tmp <span class=\"token operator\">==</span> <span class=\"token constant\">NULL</span><span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"44\"></td><td><pre>\t<span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"45\"></td><td><pre>\t\t<span class=\"token function\">perror</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"malloc\"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"46\"></td><td><pre>\t\t<span class=\"token keyword\">return</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"47\"></td><td><pre>\t<span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"48\"></td><td><pre></pre></td></tr><tr><td data-num=\"49\"></td><td><pre>\t<span class=\"token function\">_MergeSort</span><span class=\"token punctuation\">(</span>arr<span class=\"token punctuation\">,</span> <span class=\"token number\">0</span><span class=\"token punctuation\">,</span> n <span class=\"token operator\">-</span> <span class=\"token number\">1</span><span class=\"token punctuation\">,</span> tmp<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"50\"></td><td><pre></pre></td></tr><tr><td data-num=\"51\"></td><td><pre>\t<span class=\"token function\">free</span><span class=\"token punctuation\">(</span>tmp<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"52\"></td><td><pre>\ttmp <span class=\"token operator\">=</span> <span class=\"token constant\">NULL</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"53\"></td><td><pre><span class=\"token punctuation\">&#125;</span></pre></td></tr></table></figure><h6 id=\"非递归实现\"><a class=\"anchor\" href=\"#非递归实现\">#</a> 非递归实现</h6>\n<p>同样的，归并排序的递归也可以整合为非递归的形式：</p>\n<figure class=\"highlight c\"><figcaption data-lang=\"c\"><span>归并排序 非递归</span></figcaption><table><tr><td data-num=\"1\"></td><td><pre><span class=\"token keyword\">void</span> <span class=\"token function\">MergeSortNonR</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">int</span><span class=\"token operator\">*</span> arr<span class=\"token punctuation\">,</span> <span class=\"token keyword\">int</span> n<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"2\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"3\"></td><td><pre>\t<span class=\"token keyword\">int</span><span class=\"token operator\">*</span> tmp <span class=\"token operator\">=</span> <span class=\"token punctuation\">(</span><span class=\"token keyword\">int</span><span class=\"token operator\">*</span><span class=\"token punctuation\">)</span><span class=\"token function\">malloc</span><span class=\"token punctuation\">(</span>n <span class=\"token operator\">*</span> <span class=\"token keyword\">sizeof</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">int</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"4\"></td><td><pre>\t<span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>tmp <span class=\"token operator\">==</span> <span class=\"token constant\">NULL</span><span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"5\"></td><td><pre>\t<span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"6\"></td><td><pre>\t\t<span class=\"token function\">perror</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"malloc fail\"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"7\"></td><td><pre>\t\t<span class=\"token keyword\">return</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"8\"></td><td><pre>\t<span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"9\"></td><td><pre>\t<span class=\"token keyword\">for</span> <span class=\"token punctuation\">(</span><span class=\"token keyword\">int</span> gap <span class=\"token operator\">=</span> <span class=\"token number\">1</span><span class=\"token punctuation\">;</span> gap <span class=\"token operator\">&lt;</span> n<span class=\"token punctuation\">;</span> gap <span class=\"token operator\">*=</span> <span class=\"token number\">2</span><span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"10\"></td><td><pre>\t<span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"11\"></td><td><pre>\t\t<span class=\"token keyword\">for</span> <span class=\"token punctuation\">(</span><span class=\"token keyword\">int</span> j <span class=\"token operator\">=</span> <span class=\"token number\">0</span><span class=\"token punctuation\">;</span> j <span class=\"token operator\">&lt;</span> n<span class=\"token punctuation\">;</span> j <span class=\"token operator\">+=</span> <span class=\"token number\">2</span> <span class=\"token operator\">*</span> gap<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"12\"></td><td><pre>\t\t<span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"13\"></td><td><pre>\t\t\t<span class=\"token keyword\">int</span> begin1 <span class=\"token operator\">=</span> j<span class=\"token punctuation\">,</span> end1 <span class=\"token operator\">=</span> begin1 <span class=\"token operator\">+</span> gap <span class=\"token operator\">-</span> <span class=\"token number\">1</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"14\"></td><td><pre>\t\t\t<span class=\"token keyword\">int</span> begin2 <span class=\"token operator\">=</span> begin1 <span class=\"token operator\">+</span> gap<span class=\"token punctuation\">,</span> end2 <span class=\"token operator\">=</span> begin2 <span class=\"token operator\">+</span> gap <span class=\"token operator\">-</span> <span class=\"token number\">1</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"15\"></td><td><pre>\t\t\t<span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>end1 <span class=\"token operator\">>=</span> n <span class=\"token operator\">||</span> begin2 <span class=\"token operator\">>=</span> n<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"16\"></td><td><pre>\t\t\t<span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"17\"></td><td><pre>\t\t\t\t<span class=\"token keyword\">break</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"18\"></td><td><pre>\t\t\t<span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"19\"></td><td><pre>\t\t\t<span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>end2 <span class=\"token operator\">>=</span> n<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"20\"></td><td><pre>\t\t\t<span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"21\"></td><td><pre>\t\t\t\tend2 <span class=\"token operator\">=</span> n <span class=\"token operator\">-</span> <span class=\"token number\">1</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"22\"></td><td><pre>\t\t\t<span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"23\"></td><td><pre>\t\t\t<span class=\"token keyword\">int</span> i <span class=\"token operator\">=</span> j<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"24\"></td><td><pre>\t\t\t<span class=\"token keyword\">while</span> <span class=\"token punctuation\">(</span>begin1 <span class=\"token operator\">&lt;=</span> end1 <span class=\"token operator\">&amp;&amp;</span> begin2 <span class=\"token operator\">&lt;=</span> end2<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"25\"></td><td><pre>\t\t\t<span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"26\"></td><td><pre>\t\t\t\t<span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>arr<span class=\"token punctuation\">[</span>begin1<span class=\"token punctuation\">]</span> <span class=\"token operator\">&lt;</span> arr<span class=\"token punctuation\">[</span>begin2<span class=\"token punctuation\">]</span><span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"27\"></td><td><pre>\t\t\t\t<span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"28\"></td><td><pre>\t\t\t\t\ttmp<span class=\"token punctuation\">[</span>i<span class=\"token operator\">++</span><span class=\"token punctuation\">]</span> <span class=\"token operator\">=</span> arr<span class=\"token punctuation\">[</span>begin1<span class=\"token operator\">++</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"29\"></td><td><pre>\t\t\t\t<span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"30\"></td><td><pre>\t\t\t\t<span class=\"token keyword\">else</span></pre></td></tr><tr><td data-num=\"31\"></td><td><pre>\t\t\t\t<span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"32\"></td><td><pre>\t\t\t\t\ttmp<span class=\"token punctuation\">[</span>i<span class=\"token operator\">++</span><span class=\"token punctuation\">]</span> <span class=\"token operator\">=</span> arr<span class=\"token punctuation\">[</span>begin2<span class=\"token operator\">++</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"33\"></td><td><pre>\t\t\t\t<span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"34\"></td><td><pre>\t\t\t<span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"35\"></td><td><pre>\t\t\t<span class=\"token keyword\">while</span> <span class=\"token punctuation\">(</span>begin1 <span class=\"token operator\">&lt;=</span> end1<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"36\"></td><td><pre>\t\t\t<span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"37\"></td><td><pre>\t\t\t\ttmp<span class=\"token punctuation\">[</span>i<span class=\"token operator\">++</span><span class=\"token punctuation\">]</span> <span class=\"token operator\">=</span> arr<span class=\"token punctuation\">[</span>begin1<span class=\"token operator\">++</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"38\"></td><td><pre>\t\t\t<span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"39\"></td><td><pre>\t\t\t<span class=\"token keyword\">while</span> <span class=\"token punctuation\">(</span>begin2 <span class=\"token operator\">&lt;=</span> end2<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"40\"></td><td><pre>\t\t\t<span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"41\"></td><td><pre>\t\t\t\ttmp<span class=\"token punctuation\">[</span>i<span class=\"token operator\">++</span><span class=\"token punctuation\">]</span> <span class=\"token operator\">=</span> arr<span class=\"token punctuation\">[</span>begin2<span class=\"token operator\">++</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"42\"></td><td><pre>\t\t\t<span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"43\"></td><td><pre>\t\t\t<span class=\"token function\">memcpy</span><span class=\"token punctuation\">(</span>arr <span class=\"token operator\">+</span> j<span class=\"token punctuation\">,</span> tmp <span class=\"token operator\">+</span> j<span class=\"token punctuation\">,</span> <span class=\"token keyword\">sizeof</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">int</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">*</span> <span class=\"token punctuation\">(</span>end2 <span class=\"token operator\">-</span> j <span class=\"token operator\">+</span> <span class=\"token number\">1</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\t<span class=\"token comment\">// 用 j 不用 begin1，begin1 已经改变</span></pre></td></tr><tr><td data-num=\"44\"></td><td><pre>\t\t<span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"45\"></td><td><pre>\t<span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"46\"></td><td><pre>\t<span class=\"token function\">free</span><span class=\"token punctuation\">(</span>tmp<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"47\"></td><td><pre>\ttmp <span class=\"token operator\">=</span> <span class=\"token constant\">NULL</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"48\"></td><td><pre><span class=\"token punctuation\">&#125;</span></pre></td></tr></table></figure><h5 id=\"测试\"><a class=\"anchor\" href=\"#测试\">#</a> 测试</h5>\n<p>下面是对一千万个随机数据的排序测试</p>\n<p><img data-src=\"test1.png\" alt=\"一千万随机数据测试归并排序\" /></p>\n<h5 id=\"稳定性\"><a class=\"anchor\" href=\"#稳定性\">#</a> 稳定性</h5>\n<p>归并排序是稳定的。</p>\n<h3 id=\"五-非比较排序\"><a class=\"anchor\" href=\"#五-非比较排序\">#</a> 五、非比较排序</h3>\n<p>非比较排序不通过直接比较元素之间的大小关系来排序，而是利用其他方法，如数字或者字符串的特性。</p>\n<p>非比较排序往往能达到<mark>非常非常高的时间效率</mark>，但是也往往受到<mark>非常大的使用限制</mark>。</p>\n<h4 id=\"51-计数排序\"><a class=\"anchor\" href=\"#51-计数排序\">#</a> 5.1 计数排序</h4>\n<p>计数排序使用一个额外的数组来记录每个值的出现次数，然后根据这些计数来组织输出排序结果。</p>\n<p>计数排序的步骤：</p>\n<ol>\n<li><strong>找出待排序数组中的最大值和最小值</strong>，确定计数数组的长度。</li>\n<li><strong>创建并初始化计数数组</strong>，索引代表原数组中的元素，值代表该元素出现的次数。</li>\n<li><strong>遍历原数组，更新计数数组</strong>：对于原数组中的每一个元素，将计数数组对应索引的值增加 1。</li>\n<li><strong>根据计数数组，重构原数组</strong>：遍历计数数组，根据每个索引的计数，在原数组中按顺序填充相应的元素。</li>\n</ol>\n<h5 id=\"时间复杂度-2\"><a class=\"anchor\" href=\"#时间复杂度-2\">#</a> 时间复杂度</h5>\n<p>计数排序的时间复杂度是<span class=\"katex\"><span class=\"katex-mathml\"><math xmlns=\"http://www.w3.org/1998/Math/MathML\"><semantics><mrow><mi>O</mi><mo stretchy=\"false\">(</mo><mi>N</mi><mo>+</mo><mi>K</mi><mo stretchy=\"false\">)</mo></mrow><annotation encoding=\"application/x-tex\">O(N+K)</annotation></semantics></math></span><span class=\"katex-html\" aria-hidden=\"true\"><span class=\"base\"><span class=\"strut\" style=\"height:1em;vertical-align:-0.25em;\"></span><span class=\"mord mathnormal\" style=\"margin-right:0.02778em;\">O</span><span class=\"mopen\">(</span><span class=\"mord mathnormal\" style=\"margin-right:0.10903em;\">N</span><span class=\"mspace\" style=\"margin-right:0.2222222222222222em;\"></span><span class=\"mbin\">+</span><span class=\"mspace\" style=\"margin-right:0.2222222222222222em;\"></span></span><span class=\"base\"><span class=\"strut\" style=\"height:1em;vertical-align:-0.25em;\"></span><span class=\"mord mathnormal\" style=\"margin-right:0.07153em;\">K</span><span class=\"mclose\">)</span></span></span></span>，其中 K 是数组中数据跨度的范围大小（比方说一个数组中所有数据都是 1，那这个跨度就是 1，如果里面有一个 1 变成了 100 万，那 K 就直接变成了 100 万）。</p>\n<p>所以说，<strong>如果数据跨度比较小，计数排序的时间复杂度就可以认为是</strong><span class=\"katex\"><span class=\"katex-mathml\"><math xmlns=\"http://www.w3.org/1998/Math/MathML\"><semantics><mrow><mi>O</mi><mo stretchy=\"false\">(</mo><mi>N</mi><mo stretchy=\"false\">)</mo></mrow><annotation encoding=\"application/x-tex\">O(N)</annotation></semantics></math></span><span class=\"katex-html\" aria-hidden=\"true\"><span class=\"base\"><span class=\"strut\" style=\"height:1em;vertical-align:-0.25em;\"></span><span class=\"mord mathnormal\" style=\"margin-right:0.02778em;\">O</span><span class=\"mopen\">(</span><span class=\"mord mathnormal\" style=\"margin-right:0.10903em;\">N</span><span class=\"mclose\">)</span></span></span></span><strong>，其效率非常离谱。</strong></p>\n<h5 id=\"实现-2\"><a class=\"anchor\" href=\"#实现-2\">#</a> 实现</h5>\n<figure class=\"highlight c\"><figcaption data-lang=\"c\"><span>计数排序</span></figcaption><table><tr><td data-num=\"1\"></td><td><pre><span class=\"token keyword\">void</span> <span class=\"token function\">CountSort</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">int</span><span class=\"token operator\">*</span> arr<span class=\"token punctuation\">,</span> <span class=\"token keyword\">int</span> n<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"2\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"3\"></td><td><pre>\t<span class=\"token keyword\">int</span> max <span class=\"token operator\">=</span> arr<span class=\"token punctuation\">[</span><span class=\"token number\">0</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"4\"></td><td><pre>\t<span class=\"token keyword\">int</span> min <span class=\"token operator\">=</span> arr<span class=\"token punctuation\">[</span><span class=\"token number\">0</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"5\"></td><td><pre>\t<span class=\"token keyword\">for</span> <span class=\"token punctuation\">(</span><span class=\"token keyword\">int</span> i <span class=\"token operator\">=</span> <span class=\"token number\">1</span><span class=\"token punctuation\">;</span> i <span class=\"token operator\">&lt;</span> n<span class=\"token punctuation\">;</span> <span class=\"token operator\">++</span>i<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"6\"></td><td><pre>\t<span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"7\"></td><td><pre>\t\t<span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>arr<span class=\"token punctuation\">[</span>i<span class=\"token punctuation\">]</span> <span class=\"token operator\">></span> max<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"8\"></td><td><pre>\t\t<span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"9\"></td><td><pre>\t\t\tmax <span class=\"token operator\">=</span> arr<span class=\"token punctuation\">[</span>i<span class=\"token punctuation\">]</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"10\"></td><td><pre>\t\t<span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"11\"></td><td><pre>\t\t<span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>arr<span class=\"token punctuation\">[</span>i<span class=\"token punctuation\">]</span> <span class=\"token operator\">&lt;</span> min<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"12\"></td><td><pre>\t\t<span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"13\"></td><td><pre>\t\t\tmin <span class=\"token operator\">=</span> arr<span class=\"token punctuation\">[</span>i<span class=\"token punctuation\">]</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"14\"></td><td><pre>\t\t<span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"15\"></td><td><pre>\t<span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"16\"></td><td><pre>\t<span class=\"token keyword\">int</span> range <span class=\"token operator\">=</span> max <span class=\"token operator\">-</span> min <span class=\"token operator\">+</span> <span class=\"token number\">1</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"17\"></td><td><pre>\t<span class=\"token keyword\">int</span><span class=\"token operator\">*</span> count <span class=\"token operator\">=</span> <span class=\"token punctuation\">(</span><span class=\"token keyword\">int</span><span class=\"token operator\">*</span><span class=\"token punctuation\">)</span><span class=\"token function\">malloc</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">sizeof</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">int</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">*</span> range<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"18\"></td><td><pre>\t<span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>count <span class=\"token operator\">==</span> <span class=\"token constant\">NULL</span><span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"19\"></td><td><pre>\t<span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"20\"></td><td><pre>\t\t<span class=\"token function\">perror</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"malloc\"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"21\"></td><td><pre>\t\t<span class=\"token keyword\">return</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"22\"></td><td><pre>\t<span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"23\"></td><td><pre>\t<span class=\"token function\">memset</span><span class=\"token punctuation\">(</span>count<span class=\"token punctuation\">,</span> <span class=\"token number\">0</span><span class=\"token punctuation\">,</span> <span class=\"token keyword\">sizeof</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">int</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">*</span> range<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"24\"></td><td><pre>\t<span class=\"token keyword\">for</span> <span class=\"token punctuation\">(</span><span class=\"token keyword\">int</span> i <span class=\"token operator\">=</span> <span class=\"token number\">0</span><span class=\"token punctuation\">;</span> i <span class=\"token operator\">&lt;</span> n<span class=\"token punctuation\">;</span> <span class=\"token operator\">++</span>i<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"25\"></td><td><pre>\t<span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"26\"></td><td><pre>\t\tcount<span class=\"token punctuation\">[</span>arr<span class=\"token punctuation\">[</span>i<span class=\"token punctuation\">]</span> <span class=\"token operator\">-</span> min<span class=\"token punctuation\">]</span><span class=\"token operator\">++</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"27\"></td><td><pre>\t<span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"28\"></td><td><pre>\t<span class=\"token keyword\">int</span> index <span class=\"token operator\">=</span> <span class=\"token number\">0</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"29\"></td><td><pre>\t<span class=\"token keyword\">for</span> <span class=\"token punctuation\">(</span><span class=\"token keyword\">int</span> i <span class=\"token operator\">=</span> <span class=\"token number\">0</span><span class=\"token punctuation\">;</span> i <span class=\"token operator\">&lt;</span> range<span class=\"token punctuation\">;</span> <span class=\"token operator\">++</span>i<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"30\"></td><td><pre>\t<span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"31\"></td><td><pre>\t\t<span class=\"token keyword\">while</span> <span class=\"token punctuation\">(</span>count<span class=\"token punctuation\">[</span>i<span class=\"token punctuation\">]</span><span class=\"token operator\">--</span><span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"32\"></td><td><pre>\t\t<span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"33\"></td><td><pre>\t\t\tarr<span class=\"token punctuation\">[</span>index<span class=\"token operator\">++</span><span class=\"token punctuation\">]</span> <span class=\"token operator\">=</span> i <span class=\"token operator\">+</span> min<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"34\"></td><td><pre>\t\t<span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"35\"></td><td><pre>\t<span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"36\"></td><td><pre>\t<span class=\"token function\">free</span><span class=\"token punctuation\">(</span>count<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"37\"></td><td><pre>\tcount <span class=\"token operator\">=</span> <span class=\"token constant\">NULL</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"38\"></td><td><pre><span class=\"token punctuation\">&#125;</span></pre></td></tr></table></figure><h5 id=\"测试-2\"><a class=\"anchor\" href=\"#测试-2\">#</a> 测试</h5>\n<p>下面是对一千万个随机数据的排序测试（数据在 0 到 32767）：</p>\n<p><img data-src=\"test2.png\" alt=\"一千万随机数据计数排序测试\" /></p>\n<p>下面是对一千万个随机数据的排序测试（数据在 0 到十亿）：</p>\n<p><img data-src=\"test3.png\" alt=\"一千万随机数据计数排序测试\" /></p>\n<h5 id=\"局限性\"><a class=\"anchor\" href=\"#局限性\">#</a> 局限性</h5>\n<p>就像上面所说，计数排序<mark>只有在数据跨度较小时能够获得极高的时间效率</mark>。而且计数排序<mark>只能用于排序整型数据</mark>。另外，其空间复杂度较高。</p>\n<h4 id=\"52-桶排序\"><a class=\"anchor\" href=\"#52-桶排序\">#</a> 5.2 桶排序</h4>\n<p><mark>注意：桶排序效率高的离谱，局限性也高的离谱，如果还是随便生成大量数据测试可能导致程序崩溃甚至电脑卡死！</mark></p>\n<p>桶排序是基于基数排序和分布的一种排序算法。其基本思想是将一个区间内的数据分散到多个有序的桶中，然后分别对每个桶中的元素进行排序，最后将各个桶中的元素按顺序合并，从而得到一个完全有序的数组。</p>\n<p>桶排序的步骤描述起来较难理解，下面在代码部分详细解释。</p>\n<h5 id=\"时间复杂度-3\"><a class=\"anchor\" href=\"#时间复杂度-3\">#</a> 时间复杂度</h5>\n<p>桶排序时间复杂度最低可达<span class=\"katex\"><span class=\"katex-mathml\"><math xmlns=\"http://www.w3.org/1998/Math/MathML\"><semantics><mrow><mi>O</mi><mo stretchy=\"false\">(</mo><mi>N</mi><mo stretchy=\"false\">)</mo></mrow><annotation encoding=\"application/x-tex\">O(N)</annotation></semantics></math></span><span class=\"katex-html\" aria-hidden=\"true\"><span class=\"base\"><span class=\"strut\" style=\"height:1em;vertical-align:-0.25em;\"></span><span class=\"mord mathnormal\" style=\"margin-right:0.02778em;\">O</span><span class=\"mopen\">(</span><span class=\"mord mathnormal\" style=\"margin-right:0.10903em;\">N</span><span class=\"mclose\">)</span></span></span></span>，非常高。<strong>但是但凡数据跨度比较大、bucketsize（下面会解释是什么）选取的函数不那么合适，就会导致时间和空间复杂度剧烈变化，可能直接造成代码崩溃。</strong></p>\n<h5 id=\"实现-3\"><a class=\"anchor\" href=\"#实现-3\">#</a> 实现</h5>\n<figure class=\"highlight c\"><figcaption data-lang=\"c\"><span>桶排序</span></figcaption><table><tr><td data-num=\"1\"></td><td><pre><span class=\"token keyword\">void</span> <span class=\"token function\">BucketSort</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">int</span><span class=\"token operator\">*</span> arr<span class=\"token punctuation\">,</span> <span class=\"token keyword\">int</span> n<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"2\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"3\"></td><td><pre>\t<span class=\"token keyword\">int</span> max <span class=\"token operator\">=</span> arr<span class=\"token punctuation\">[</span><span class=\"token number\">0</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"4\"></td><td><pre>\t<span class=\"token keyword\">int</span> min <span class=\"token operator\">=</span> arr<span class=\"token punctuation\">[</span><span class=\"token number\">0</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"5\"></td><td><pre>\t<span class=\"token keyword\">for</span> <span class=\"token punctuation\">(</span><span class=\"token keyword\">int</span> i <span class=\"token operator\">=</span> <span class=\"token number\">1</span><span class=\"token punctuation\">;</span> i <span class=\"token operator\">&lt;</span> n<span class=\"token punctuation\">;</span> <span class=\"token operator\">++</span>i<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"6\"></td><td><pre>\t<span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"7\"></td><td><pre>\t\t<span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>arr<span class=\"token punctuation\">[</span>i<span class=\"token punctuation\">]</span> <span class=\"token operator\">></span> max<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"8\"></td><td><pre>\t\t<span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"9\"></td><td><pre>\t\t\tmax <span class=\"token operator\">=</span> arr<span class=\"token punctuation\">[</span>i<span class=\"token punctuation\">]</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"10\"></td><td><pre>\t\t<span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"11\"></td><td><pre>\t\t<span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>arr<span class=\"token punctuation\">[</span>i<span class=\"token punctuation\">]</span> <span class=\"token operator\">&lt;</span> min<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"12\"></td><td><pre>\t\t<span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"13\"></td><td><pre>\t\t\tmin <span class=\"token operator\">=</span> arr<span class=\"token punctuation\">[</span>i<span class=\"token punctuation\">]</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"14\"></td><td><pre>\t\t<span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"15\"></td><td><pre>\t<span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"16\"></td><td><pre>\t<span class=\"token keyword\">int</span> range <span class=\"token operator\">=</span> max <span class=\"token operator\">-</span> min <span class=\"token operator\">+</span> <span class=\"token number\">1</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"17\"></td><td><pre>\t<span class=\"token keyword\">int</span> bucketSize <span class=\"token operator\">=</span> <span class=\"token number\">5</span><span class=\"token punctuation\">;</span>\t<span class=\"token comment\">// 这里对不同的情形需要设置不同的数字，效率差距非常大</span></pre></td></tr><tr><td data-num=\"18\"></td><td><pre>\t<span class=\"token keyword\">int</span> bucketCount <span class=\"token operator\">=</span> range <span class=\"token operator\">/</span> bucketSize <span class=\"token operator\">+</span> <span class=\"token number\">1</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"19\"></td><td><pre>\t<span class=\"token keyword\">int</span><span class=\"token operator\">*</span><span class=\"token operator\">*</span> bucket <span class=\"token operator\">=</span> <span class=\"token punctuation\">(</span><span class=\"token keyword\">int</span><span class=\"token operator\">*</span><span class=\"token operator\">*</span><span class=\"token punctuation\">)</span><span class=\"token function\">malloc</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">sizeof</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">int</span><span class=\"token operator\">*</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">*</span> bucketCount<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"20\"></td><td><pre>\t<span class=\"token keyword\">for</span> <span class=\"token punctuation\">(</span><span class=\"token keyword\">int</span> i <span class=\"token operator\">=</span> <span class=\"token number\">0</span><span class=\"token punctuation\">;</span> i <span class=\"token operator\">&lt;</span> bucketCount<span class=\"token punctuation\">;</span> <span class=\"token operator\">++</span>i<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"21\"></td><td><pre>\t<span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"22\"></td><td><pre>\t\tbucket<span class=\"token punctuation\">[</span>i<span class=\"token punctuation\">]</span> <span class=\"token operator\">=</span> <span class=\"token punctuation\">(</span><span class=\"token keyword\">int</span><span class=\"token operator\">*</span><span class=\"token punctuation\">)</span><span class=\"token function\">malloc</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">sizeof</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">int</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">*</span> n<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"23\"></td><td><pre>\t<span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"24\"></td><td><pre>\t<span class=\"token keyword\">int</span><span class=\"token operator\">*</span> count <span class=\"token operator\">=</span> <span class=\"token punctuation\">(</span><span class=\"token keyword\">int</span><span class=\"token operator\">*</span><span class=\"token punctuation\">)</span><span class=\"token function\">malloc</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">sizeof</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">int</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">*</span> bucketCount<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"25\"></td><td><pre>\t<span class=\"token function\">memset</span><span class=\"token punctuation\">(</span>count<span class=\"token punctuation\">,</span> <span class=\"token number\">0</span><span class=\"token punctuation\">,</span> <span class=\"token keyword\">sizeof</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">int</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">*</span> bucketCount<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"26\"></td><td><pre>\t<span class=\"token keyword\">for</span> <span class=\"token punctuation\">(</span><span class=\"token keyword\">int</span> i <span class=\"token operator\">=</span> <span class=\"token number\">0</span><span class=\"token punctuation\">;</span> i <span class=\"token operator\">&lt;</span> n<span class=\"token punctuation\">;</span> <span class=\"token operator\">++</span>i<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"27\"></td><td><pre>\t<span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"28\"></td><td><pre>\t\t<span class=\"token keyword\">int</span> index <span class=\"token operator\">=</span> <span class=\"token punctuation\">(</span>arr<span class=\"token punctuation\">[</span>i<span class=\"token punctuation\">]</span> <span class=\"token operator\">-</span> min<span class=\"token punctuation\">)</span> <span class=\"token operator\">/</span> bucketSize<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"29\"></td><td><pre>\t\tbucket<span class=\"token punctuation\">[</span>index<span class=\"token punctuation\">]</span><span class=\"token punctuation\">[</span>count<span class=\"token punctuation\">[</span>index<span class=\"token punctuation\">]</span><span class=\"token operator\">++</span><span class=\"token punctuation\">]</span> <span class=\"token operator\">=</span> arr<span class=\"token punctuation\">[</span>i<span class=\"token punctuation\">]</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"30\"></td><td><pre>\t<span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"31\"></td><td><pre>\t<span class=\"token keyword\">int</span> index <span class=\"token operator\">=</span> <span class=\"token number\">0</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"32\"></td><td><pre>\t<span class=\"token keyword\">for</span> <span class=\"token punctuation\">(</span><span class=\"token keyword\">int</span> i <span class=\"token operator\">=</span> <span class=\"token number\">0</span><span class=\"token punctuation\">;</span> i <span class=\"token operator\">&lt;</span> bucketCount<span class=\"token punctuation\">;</span> <span class=\"token operator\">++</span>i<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"33\"></td><td><pre>\t<span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"34\"></td><td><pre>\t\t<span class=\"token function\">InsertSort</span><span class=\"token punctuation\">(</span>bucket<span class=\"token punctuation\">[</span>i<span class=\"token punctuation\">]</span><span class=\"token punctuation\">,</span> count<span class=\"token punctuation\">[</span>i<span class=\"token punctuation\">]</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\t<span class=\"token comment\">// 采用插入排序只是一种方法，这里不唯一</span></pre></td></tr><tr><td data-num=\"35\"></td><td><pre>\t\t<span class=\"token keyword\">for</span> <span class=\"token punctuation\">(</span><span class=\"token keyword\">int</span> j <span class=\"token operator\">=</span> <span class=\"token number\">0</span><span class=\"token punctuation\">;</span> j <span class=\"token operator\">&lt;</span> count<span class=\"token punctuation\">[</span>i<span class=\"token punctuation\">]</span><span class=\"token punctuation\">;</span> <span class=\"token operator\">++</span>j<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"36\"></td><td><pre>\t\t<span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"37\"></td><td><pre>\t\t\tarr<span class=\"token punctuation\">[</span>index<span class=\"token operator\">++</span><span class=\"token punctuation\">]</span> <span class=\"token operator\">=</span> bucket<span class=\"token punctuation\">[</span>i<span class=\"token punctuation\">]</span><span class=\"token punctuation\">[</span>j<span class=\"token punctuation\">]</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"38\"></td><td><pre>\t\t<span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"39\"></td><td><pre>\t<span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"40\"></td><td><pre>\t<span class=\"token keyword\">for</span> <span class=\"token punctuation\">(</span><span class=\"token keyword\">int</span> i <span class=\"token operator\">=</span> <span class=\"token number\">0</span><span class=\"token punctuation\">;</span> i <span class=\"token operator\">&lt;</span> bucketCount<span class=\"token punctuation\">;</span> <span class=\"token operator\">++</span>i<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"41\"></td><td><pre>\t<span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"42\"></td><td><pre>\t\t<span class=\"token function\">free</span><span class=\"token punctuation\">(</span>bucket<span class=\"token punctuation\">[</span>i<span class=\"token punctuation\">]</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"43\"></td><td><pre>\t<span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"44\"></td><td><pre>\t<span class=\"token function\">free</span><span class=\"token punctuation\">(</span>bucket<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"45\"></td><td><pre>\tbucket <span class=\"token operator\">=</span> <span class=\"token constant\">NULL</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"46\"></td><td><pre>\t<span class=\"token function\">free</span><span class=\"token punctuation\">(</span>count<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"47\"></td><td><pre>\tcount <span class=\"token operator\">=</span> <span class=\"token constant\">NULL</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"48\"></td><td><pre><span class=\"token punctuation\">&#125;</span></pre></td></tr></table></figure><p>在上方实现中，我们首先确定了数据范围 range。</p>\n<p>然后我们要根据 range 确定每一个桶内我们要存放范围大小为多少的数据，也就是 bucketSize。<mark>注意，这不是说每个 bucket 只能放 bucketSize 个数据，而是可以放多少值不同的数据（相同值可以无限叠放）。</mark></p>\n<p>随后我们就计算出了桶的数量 bucketCount，并且创建了这么多桶。同时每一个桶都配备了一个计数器（对应到 count 数组里）。</p>\n<p>最后就是与计数排序类似的步骤，数据分桶再收集即可。</p>\n<h5 id=\"测试-3\"><a class=\"anchor\" href=\"#测试-3\">#</a> 测试</h5>\n<p>100 万 0~99 的数据，bucketSize = 2：</p>\n<p><img data-src=\"test6.png\" alt=\"桶排序，bucketSize=2\" /></p>\n<p>100 万 0~99 的数据，bucketSize = 5：</p>\n<p><img data-src=\"test7.png\" alt=\"桶排序，bucketSize=5\" /></p>\n<p>100 万 0~99 的数据，bucketSize = 1：</p>\n<p><img data-src=\"test8.png\" alt=\"桶排序，bucketSize=1\" /></p>\n<h4 id=\"53-基数排序\"><a class=\"anchor\" href=\"#53-基数排序\">#</a> 5.3 基数排序</h4>\n<p><img data-src=\"%E5%9F%BA%E6%95%B0%E6%8E%92%E5%BA%8F.gif\" alt=\"基数排序\" /></p>\n<p>基数排序是对计数排序的一个升级方法。只要我们 == 把数组中的数从低位到高位逐次进行只看某一位的计数排序，最终就能得到有序的数组。== 这可能有些难以理解，但是我们可以看一个例子：</p>\n<blockquote>\n<p>数组 =[170,45,75,90,802,24,2,66]</p>\n<p>我们将按照十进制的个位、十位、百位等进行排序。这里最大的数字是 802，有三位数字，所以我们将进行三轮排序。</p>\n<p>第一轮：按个位排序</p>\n<ul>\n<li>170 的个位是 0</li>\n<li>45 的个位是 5</li>\n<li>75 的个位是 5</li>\n<li>90 的个位是 0</li>\n<li>802 的个位是 2</li>\n<li>24 的个位是 4</li>\n<li>2 的个位是 2</li>\n<li>66 的个位是 6</li>\n</ul>\n<p>按个位排序的结果为：170,90,802,2,24,45,75,66170,90,802,2,24,45,75,66</p>\n<p>第二轮：按十位排序</p>\n<ul>\n<li>170 的十位是 7</li>\n<li>90 的十位是 9</li>\n<li>802 的十位是 0</li>\n<li>2 的十位是 0（没有十位，视为 0）</li>\n<li>24 的十位是 2</li>\n<li>45 的十位是 4</li>\n<li>75 的十位是 7</li>\n<li>66 的十位是 6</li>\n</ul>\n<p>按十位排序的结果为：802,2,24,45,66,170,75,90802,2,24,45,66,170,75,90</p>\n<p>第三轮：按百位排序</p>\n<ul>\n<li>802 的百位是 8</li>\n<li>2 的百位是 0（没有百位，视为 0）</li>\n<li>24 的百位是 0</li>\n<li>45 的百位是 0</li>\n<li>66 的百位是 0</li>\n<li>170 的百位是 1</li>\n<li>75 的百位是 0</li>\n<li>90 的百位是 0</li>\n</ul>\n<p>按百位排序的结果为：2,24,45,66,75,90,170,8022,24,45,66,75,90,170,802</p>\n<p>最终排序结果为：2,24,45,66,75,90,170,8022,24,45,66,75,90,170,802</p>\n</blockquote>\n<h5 id=\"时间复杂度-4\"><a class=\"anchor\" href=\"#时间复杂度-4\">#</a> 时间复杂度</h5>\n<p>基数排序的时间复杂度仅为<span class=\"katex\"><span class=\"katex-mathml\"><math xmlns=\"http://www.w3.org/1998/Math/MathML\"><semantics><mrow><mi>O</mi><mo stretchy=\"false\">(</mo><mi>k</mi><mo>×</mo><mtext> </mtext><mi>N</mi><mo stretchy=\"false\">)</mo></mrow><annotation encoding=\"application/x-tex\">O(k\\times\\,N)</annotation></semantics></math></span><span class=\"katex-html\" aria-hidden=\"true\"><span class=\"base\"><span class=\"strut\" style=\"height:1em;vertical-align:-0.25em;\"></span><span class=\"mord mathnormal\" style=\"margin-right:0.02778em;\">O</span><span class=\"mopen\">(</span><span class=\"mord mathnormal\" style=\"margin-right:0.03148em;\">k</span><span class=\"mspace\" style=\"margin-right:0.2222222222222222em;\"></span><span class=\"mbin\">×</span><span class=\"mspace\" style=\"margin-right:0.16666666666666666em;\"></span><span class=\"mspace\" style=\"margin-right:0.2222222222222222em;\"></span></span><span class=\"base\"><span class=\"strut\" style=\"height:1em;vertical-align:-0.25em;\"></span><span class=\"mord mathnormal\" style=\"margin-right:0.10903em;\">N</span><span class=\"mclose\">)</span></span></span></span>，非常高效。</p>\n<h5 id=\"实现-4\"><a class=\"anchor\" href=\"#实现-4\">#</a> 实现</h5>\n<figure class=\"highlight c\"><figcaption data-lang=\"c\"><span>基数排序</span></figcaption><table><tr><td data-num=\"1\"></td><td><pre><span class=\"token keyword\">void</span> <span class=\"token function\">RadixSort</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">int</span><span class=\"token operator\">*</span> arr<span class=\"token punctuation\">,</span> <span class=\"token keyword\">int</span> n<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"2\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"3\"></td><td><pre>\t<span class=\"token keyword\">int</span> max <span class=\"token operator\">=</span> arr<span class=\"token punctuation\">[</span><span class=\"token number\">0</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"4\"></td><td><pre>\t<span class=\"token keyword\">for</span> <span class=\"token punctuation\">(</span><span class=\"token keyword\">int</span> i <span class=\"token operator\">=</span> <span class=\"token number\">1</span><span class=\"token punctuation\">;</span> i <span class=\"token operator\">&lt;</span> n<span class=\"token punctuation\">;</span> <span class=\"token operator\">++</span>i<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"5\"></td><td><pre>\t<span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"6\"></td><td><pre>\t\t<span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>arr<span class=\"token punctuation\">[</span>i<span class=\"token punctuation\">]</span> <span class=\"token operator\">></span> max<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"7\"></td><td><pre>\t\t<span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"8\"></td><td><pre>\t\t\tmax <span class=\"token operator\">=</span> arr<span class=\"token punctuation\">[</span>i<span class=\"token punctuation\">]</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"9\"></td><td><pre>\t\t<span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"10\"></td><td><pre>\t<span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"11\"></td><td><pre>\t<span class=\"token keyword\">int</span> maxDigit <span class=\"token operator\">=</span> <span class=\"token number\">0</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"12\"></td><td><pre>\t<span class=\"token keyword\">while</span> <span class=\"token punctuation\">(</span>max<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"13\"></td><td><pre>\t<span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"14\"></td><td><pre>\t\tmax <span class=\"token operator\">/=</span> <span class=\"token number\">10</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"15\"></td><td><pre>\t\t<span class=\"token operator\">++</span>maxDigit<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"16\"></td><td><pre>\t<span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"17\"></td><td><pre>\t<span class=\"token keyword\">int</span><span class=\"token operator\">*</span> count <span class=\"token operator\">=</span> <span class=\"token punctuation\">(</span><span class=\"token keyword\">int</span><span class=\"token operator\">*</span><span class=\"token punctuation\">)</span><span class=\"token function\">malloc</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">sizeof</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">int</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">*</span> <span class=\"token number\">10</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"18\"></td><td><pre>\t<span class=\"token keyword\">int</span><span class=\"token operator\">*</span> bucket <span class=\"token operator\">=</span> <span class=\"token punctuation\">(</span><span class=\"token keyword\">int</span><span class=\"token operator\">*</span><span class=\"token punctuation\">)</span><span class=\"token function\">malloc</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">sizeof</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">int</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">*</span> n<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"19\"></td><td><pre>\t<span class=\"token keyword\">int</span> radix <span class=\"token operator\">=</span> <span class=\"token number\">1</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"20\"></td><td><pre>\t<span class=\"token keyword\">for</span> <span class=\"token punctuation\">(</span><span class=\"token keyword\">int</span> i <span class=\"token operator\">=</span> <span class=\"token number\">0</span><span class=\"token punctuation\">;</span> i <span class=\"token operator\">&lt;</span> maxDigit<span class=\"token punctuation\">;</span> <span class=\"token operator\">++</span>i<span class=\"token punctuation\">)</span>\t<span class=\"token comment\">//@</span></pre></td></tr><tr><td data-num=\"21\"></td><td><pre>\t<span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"22\"></td><td><pre>\t\t<span class=\"token function\">memset</span><span class=\"token punctuation\">(</span>count<span class=\"token punctuation\">,</span> <span class=\"token number\">0</span><span class=\"token punctuation\">,</span> <span class=\"token keyword\">sizeof</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">int</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">*</span> <span class=\"token number\">10</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"23\"></td><td><pre>\t\t<span class=\"token keyword\">for</span> <span class=\"token punctuation\">(</span><span class=\"token keyword\">int</span> j <span class=\"token operator\">=</span> <span class=\"token number\">0</span><span class=\"token punctuation\">;</span> j <span class=\"token operator\">&lt;</span> n<span class=\"token punctuation\">;</span> <span class=\"token operator\">++</span>j<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"24\"></td><td><pre>\t\t<span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"25\"></td><td><pre>\t\t\tcount<span class=\"token punctuation\">[</span><span class=\"token punctuation\">(</span>arr<span class=\"token punctuation\">[</span>j<span class=\"token punctuation\">]</span> <span class=\"token operator\">/</span> radix<span class=\"token punctuation\">)</span> <span class=\"token operator\">%</span> <span class=\"token number\">10</span><span class=\"token punctuation\">]</span><span class=\"token operator\">++</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"26\"></td><td><pre>\t\t<span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"27\"></td><td><pre>\t\t<span class=\"token keyword\">for</span> <span class=\"token punctuation\">(</span><span class=\"token keyword\">int</span> j <span class=\"token operator\">=</span> <span class=\"token number\">1</span><span class=\"token punctuation\">;</span> j <span class=\"token operator\">&lt;</span> <span class=\"token number\">10</span><span class=\"token punctuation\">;</span> <span class=\"token operator\">++</span>j<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"28\"></td><td><pre>\t\t<span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"29\"></td><td><pre>\t\t\tcount<span class=\"token punctuation\">[</span>j<span class=\"token punctuation\">]</span> <span class=\"token operator\">+=</span> count<span class=\"token punctuation\">[</span>j <span class=\"token operator\">-</span> <span class=\"token number\">1</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"30\"></td><td><pre>\t\t<span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"31\"></td><td><pre>\t\t<span class=\"token keyword\">for</span> <span class=\"token punctuation\">(</span><span class=\"token keyword\">int</span> j <span class=\"token operator\">=</span> n <span class=\"token operator\">-</span> <span class=\"token number\">1</span><span class=\"token punctuation\">;</span> j <span class=\"token operator\">>=</span> <span class=\"token number\">0</span><span class=\"token punctuation\">;</span> <span class=\"token operator\">--</span>j<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"32\"></td><td><pre>\t\t<span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"33\"></td><td><pre>\t\t\tbucket<span class=\"token punctuation\">[</span><span class=\"token operator\">--</span>count<span class=\"token punctuation\">[</span><span class=\"token punctuation\">(</span>arr<span class=\"token punctuation\">[</span>j<span class=\"token punctuation\">]</span> <span class=\"token operator\">/</span> radix<span class=\"token punctuation\">)</span> <span class=\"token operator\">%</span> <span class=\"token number\">10</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">]</span> <span class=\"token operator\">=</span> arr<span class=\"token punctuation\">[</span>j<span class=\"token punctuation\">]</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"34\"></td><td><pre>\t\t<span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"35\"></td><td><pre>\t\t<span class=\"token function\">memcpy</span><span class=\"token punctuation\">(</span>arr<span class=\"token punctuation\">,</span> bucket<span class=\"token punctuation\">,</span> <span class=\"token keyword\">sizeof</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">int</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">*</span> n<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"36\"></td><td><pre>\t\tradix <span class=\"token operator\">*=</span> <span class=\"token number\">10</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"37\"></td><td><pre>\t<span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"38\"></td><td><pre>\t<span class=\"token function\">free</span><span class=\"token punctuation\">(</span>count<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"39\"></td><td><pre>\tcount <span class=\"token operator\">=</span> <span class=\"token constant\">NULL</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"40\"></td><td><pre>\t<span class=\"token function\">free</span><span class=\"token punctuation\">(</span>bucket<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"41\"></td><td><pre>\tbucket <span class=\"token operator\">=</span> <span class=\"token constant\">NULL</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"42\"></td><td><pre><span class=\"token punctuation\">&#125;</span></pre></td></tr></table></figure><p>对于上方 @标记的循环体中的 3 个子循环，这里需要给出一些解锁：</p>\n<ol>\n<li>\n<p>第一个 for 循环</p>\n<p>循环遍历整个数组，计算当前位的数字（个位、十位、百位等），并对应的增加 count 数组中对应索引的值。这里<span class=\"katex\"><span class=\"katex-mathml\"><math xmlns=\"http://www.w3.org/1998/Math/MathML\"><semantics><mrow><mi>a</mi><mi>r</mi><mi>r</mi><mo stretchy=\"false\">[</mo><mi>j</mi><mo stretchy=\"false\">]</mo><mi mathvariant=\"normal\">/</mi><mi>r</mi><mi>a</mi><mi>d</mi><mi>i</mi><mi>x</mi><mi mathvariant=\"normal\">%</mi><mtext> </mtext><mn>10</mn></mrow><annotation encoding=\"application/x-tex\">arr[j]/radix\\%\\,10</annotation></semantics></math></span><span class=\"katex-html\" aria-hidden=\"true\"><span class=\"base\"><span class=\"strut\" style=\"height:1em;vertical-align:-0.25em;\"></span><span class=\"mord mathnormal\">a</span><span class=\"mord mathnormal\" style=\"margin-right:0.02778em;\">r</span><span class=\"mord mathnormal\" style=\"margin-right:0.02778em;\">r</span><span class=\"mopen\">[</span><span class=\"mord mathnormal\" style=\"margin-right:0.05724em;\">j</span><span class=\"mclose\">]</span><span class=\"mord\">/</span><span class=\"mord mathnormal\" style=\"margin-right:0.02778em;\">r</span><span class=\"mord mathnormal\">a</span><span class=\"mord mathnormal\">d</span><span class=\"mord mathnormal\">i</span><span class=\"mord mathnormal\">x</span><span class=\"mord\">%</span><span class=\"mspace\" style=\"margin-right:0.16666666666666666em;\"></span><span class=\"mord\">1</span><span class=\"mord\">0</span></span></span></span> 计算出当前位的值（如个位、十位等），count 数组用来记录每个数字（0-9）在当前位出现的次数。</p>\n</li>\n<li>\n<p>第二个 for 循环</p>\n<p>通过累加前一个索引的 count 值，将 count 数组转化为前缀和数组。这一步是为了在下一个循环中能够直接定位每个元素在 bucket 中的存放位置。每个元素的存放位置取决于它当前位的值，并使用前缀和确定其在 bucket 中的结束位置。</p>\n</li>\n<li>\n<p>第三个 for 循环</p>\n<p>从数组的最后一个元素开始向前遍历，这样可以保持排序的稳定性（即相同值的元素保持原有顺序）。通过查找当前位的数字对应的 count 数组值，确定元素在 bucket 中的位置（使用 <code>--count</code>  是为了下次遇到同样的数时位置向前移动一个单位），然后将元素放在 bucket 中相应的位置。</p>\n</li>\n</ol>\n<h5 id=\"测试-4\"><a class=\"anchor\" href=\"#测试-4\">#</a> 测试</h5>\n<p>下面是对一千万个随机数据的排序测试（数据在 0 到 32767）：</p>\n<p><img data-src=\"test4.png\" alt=\"一千万随机数据基数排序测试\" /></p>\n<p>下面是对一千万个随机数据的排序测试（数据在 0 到十亿）：</p>\n<p><img data-src=\"test5.png\" alt=\"一千万随机数据基数排序测试\" /></p>\n<h5 id=\"局限性-2\"><a class=\"anchor\" href=\"#局限性-2\">#</a> 局限性</h5>\n<p>可以看到，基数排序<mark>一定程度上减除了计数排序对大范围数据处理的劣势，但是也增加了空间复杂度</mark>。与此同时，基数排序依旧保留了计数排序只能处理整数的缺点。</p>\n",
            "tags": [
                "计算机科学",
                "数据结构笔记",
                "算法",
                "数据结构",
                "排序"
            ]
        },
        {
            "id": "https://www.starlinglin.top/computer-science/data-structure-note/%E6%A4%8B%E9%B8%9F%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84%E7%AC%94%E8%AE%B0%20%EF%BC%839%EF%BC%9A%E6%8E%92%E5%BA%8F%C2%B7%E4%B8%8A/",
            "url": "https://www.starlinglin.top/computer-science/data-structure-note/%E6%A4%8B%E9%B8%9F%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84%E7%AC%94%E8%AE%B0%20%EF%BC%839%EF%BC%9A%E6%8E%92%E5%BA%8F%C2%B7%E4%B8%8A/",
            "title": "椋鸟数据结构笔记#9：排序·上",
            "date_published": "2024-04-11T16:55:22.000Z",
            "content_html": "<div class=\"note info\">\n<p>该系列为本人的学习笔记，主要由本人整理书写而成。部分内容来自教材、视频课程等，不能保证完全原创性。</p>\n</div>\n<p>萌新的学习笔记，写错了恳请斧正。</p>\n<h3 id=\"排序的稳定性\"><a class=\"anchor\" href=\"#排序的稳定性\">#</a> 排序的稳定性</h3>\n<p>先介绍一个概念，就是排序的稳定性。</p>\n<p>排序算法的稳定性是指，如果<strong>待排序的序列中存在值相等的元素，经过排序后这些元素之间的先后顺序不变</strong>。简而言之，稳定的排序算法可以保留相等元素原本的<mark>相对顺序</mark>。</p>\n<p>假设有一组人的年龄列表，有些人年龄相同：5,3,8,3,2。</p>\n<p>如果我们对这个列表进行稳定排序，那么两个年龄为 3 的人在排序后的列表中，先出现的那个人在原列表中也是先出现的。</p>\n<p>如果排序算法是稳定的，排序后我们得到的可能是这样：2,3 (第一个),3 (第二个),5,8。</p>\n<p>如果排序算法是不稳定的，排序后可能得到：2,3 (第二个),3 (第一个),5,8，这里 3 的顺序被颠倒了，说明排序算法是不稳定的。</p>\n<p>稳定性在某些场合下是很重要的。比如，在处理多关键字排序时，稳定性可以保证前一次排序的结果在后一次排序时不会被打乱。<strong>如果一个排序算法是稳定的，那么它可以更容易地被用于复杂的排序任务中</strong>。</p>\n<h3 id=\"一-插入排序\"><a class=\"anchor\" href=\"#一-插入排序\">#</a> 一、插入排序</h3>\n<h4 id=\"11-直接插入排序insertion-sort\"><a class=\"anchor\" href=\"#11-直接插入排序insertion-sort\">#</a> 1.1 直接插入排序 (Insertion Sort)</h4>\n<p><img data-src=\"%E6%8F%92%E5%85%A5%E6%8E%92%E5%BA%8F.gif\" alt=\"插入排序\" /></p>\n<p>直接插入排序是一种简单直观的排序算法。通过构建有序序列，对于未排序数据，在已排序序列中从后向前扫描，找到相应位置并插入。插入排序在实现上，通常采用<strong>原地排序</strong>，因此适合用于小规模数据。</p>\n<p>直接插入排序的步骤：</p>\n<ol>\n<li>从第一个元素开始，该元素可以认为已经被排序。</li>\n<li>取出下一个元素，在已经排序的元素序列中从后向前扫描。</li>\n<li>如果该元素（已排序）大于新元素，将该元素移到下一位置。</li>\n<li>重复步骤 3，直到找到已排序的元素小于或者等于新元素的位置。</li>\n<li>将新元素插入到该位置后。</li>\n<li>重复步骤 2~5。</li>\n</ol>\n<h5 id=\"时间复杂度\"><a class=\"anchor\" href=\"#时间复杂度\">#</a> 时间复杂度</h5>\n<p>在<strong>最坏的情况下</strong>，插入排序的时间复杂度为<span class=\"katex\"><span class=\"katex-mathml\"><math xmlns=\"http://www.w3.org/1998/Math/MathML\"><semantics><mrow><mi>O</mi><mo stretchy=\"false\">(</mo><msup><mi>N</mi><mn>2</mn></msup><mo stretchy=\"false\">)</mo></mrow><annotation encoding=\"application/x-tex\">O(N^2)</annotation></semantics></math></span><span class=\"katex-html\" aria-hidden=\"true\"><span class=\"base\"><span class=\"strut\" style=\"height:1.064108em;vertical-align:-0.25em;\"></span><span class=\"mord mathnormal\" style=\"margin-right:0.02778em;\">O</span><span class=\"mopen\">(</span><span class=\"mord\"><span class=\"mord mathnormal\" style=\"margin-right:0.10903em;\">N</span><span class=\"msupsub\"><span class=\"vlist-t\"><span class=\"vlist-r\"><span class=\"vlist\" style=\"height:0.8141079999999999em;\"><span style=\"top:-3.063em;margin-right:0.05em;\"><span class=\"pstrut\" style=\"height:2.7em;\"></span><span class=\"sizing reset-size6 size3 mtight\"><span class=\"mord mtight\">2</span></span></span></span></span></span></span></span><span class=\"mclose\">)</span></span></span></span>，其中<span class=\"katex\"><span class=\"katex-mathml\"><math xmlns=\"http://www.w3.org/1998/Math/MathML\"><semantics><mrow><mi>N</mi></mrow><annotation encoding=\"application/x-tex\">N</annotation></semantics></math></span><span class=\"katex-html\" aria-hidden=\"true\"><span class=\"base\"><span class=\"strut\" style=\"height:0.68333em;vertical-align:0em;\"></span><span class=\"mord mathnormal\" style=\"margin-right:0.10903em;\">N</span></span></span></span> 是数组的长度。在<strong>最好的情况下</strong>，如果数组已经是排好序的，插入排序的时间复杂度可以降低到<span class=\"katex\"><span class=\"katex-mathml\"><math xmlns=\"http://www.w3.org/1998/Math/MathML\"><semantics><mrow><mi>O</mi><mo stretchy=\"false\">(</mo><mi>N</mi><mo stretchy=\"false\">)</mo></mrow><annotation encoding=\"application/x-tex\">O(N)</annotation></semantics></math></span><span class=\"katex-html\" aria-hidden=\"true\"><span class=\"base\"><span class=\"strut\" style=\"height:1em;vertical-align:-0.25em;\"></span><span class=\"mord mathnormal\" style=\"margin-right:0.02778em;\">O</span><span class=\"mopen\">(</span><span class=\"mord mathnormal\" style=\"margin-right:0.10903em;\">N</span><span class=\"mclose\">)</span></span></span></span>，<strong>平均来说</strong>，其复杂度更接近<span class=\"katex\"><span class=\"katex-mathml\"><math xmlns=\"http://www.w3.org/1998/Math/MathML\"><semantics><mrow><mi>O</mi><mo stretchy=\"false\">(</mo><msup><mi>N</mi><mn>2</mn></msup><mo stretchy=\"false\">)</mo></mrow><annotation encoding=\"application/x-tex\">O(N^2)</annotation></semantics></math></span><span class=\"katex-html\" aria-hidden=\"true\"><span class=\"base\"><span class=\"strut\" style=\"height:1.064108em;vertical-align:-0.25em;\"></span><span class=\"mord mathnormal\" style=\"margin-right:0.02778em;\">O</span><span class=\"mopen\">(</span><span class=\"mord\"><span class=\"mord mathnormal\" style=\"margin-right:0.10903em;\">N</span><span class=\"msupsub\"><span class=\"vlist-t\"><span class=\"vlist-r\"><span class=\"vlist\" style=\"height:0.8141079999999999em;\"><span style=\"top:-3.063em;margin-right:0.05em;\"><span class=\"pstrut\" style=\"height:2.7em;\"></span><span class=\"sizing reset-size6 size3 mtight\"><span class=\"mord mtight\">2</span></span></span></span></span></span></span></span><span class=\"mclose\">)</span></span></span></span>。<strong>适用于小规模数据的排序或者原本就接近有序的情况。</strong></p>\n<h5 id=\"实现\"><a class=\"anchor\" href=\"#实现\">#</a> 实现</h5>\n<figure class=\"highlight c\"><figcaption data-lang=\"c\"><span>直接插入排序</span></figcaption><table><tr><td data-num=\"1\"></td><td><pre><span class=\"token keyword\">void</span> <span class=\"token function\">InsertSort</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">int</span><span class=\"token operator\">*</span> arr<span class=\"token punctuation\">,</span> <span class=\"token keyword\">int</span> n<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"2\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"3\"></td><td><pre>\t<span class=\"token keyword\">for</span> <span class=\"token punctuation\">(</span><span class=\"token keyword\">int</span> i <span class=\"token operator\">=</span> <span class=\"token number\">0</span><span class=\"token punctuation\">;</span> i <span class=\"token operator\">&lt;</span> n <span class=\"token operator\">-</span> <span class=\"token number\">1</span><span class=\"token punctuation\">;</span> <span class=\"token operator\">++</span>i<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"4\"></td><td><pre>\t<span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"5\"></td><td><pre>\t\t<span class=\"token keyword\">int</span> end <span class=\"token operator\">=</span> i<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"6\"></td><td><pre>\t\t<span class=\"token keyword\">int</span> tmp <span class=\"token operator\">=</span> arr<span class=\"token punctuation\">[</span>end <span class=\"token operator\">+</span> <span class=\"token number\">1</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"7\"></td><td><pre>\t\t<span class=\"token keyword\">while</span> <span class=\"token punctuation\">(</span>end <span class=\"token operator\">>=</span> <span class=\"token number\">0</span><span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"8\"></td><td><pre>\t\t<span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"9\"></td><td><pre>\t\t\t<span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>tmp <span class=\"token operator\">&lt;</span> arr<span class=\"token punctuation\">[</span>end<span class=\"token punctuation\">]</span><span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"10\"></td><td><pre>\t\t\t<span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"11\"></td><td><pre>\t\t\t\tarr<span class=\"token punctuation\">[</span>end <span class=\"token operator\">+</span> <span class=\"token number\">1</span><span class=\"token punctuation\">]</span> <span class=\"token operator\">=</span> arr<span class=\"token punctuation\">[</span>end<span class=\"token punctuation\">]</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"12\"></td><td><pre>\t\t\t\t<span class=\"token operator\">--</span>end<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"13\"></td><td><pre>\t\t\t<span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"14\"></td><td><pre>\t\t\t<span class=\"token keyword\">else</span></pre></td></tr><tr><td data-num=\"15\"></td><td><pre>\t\t\t<span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"16\"></td><td><pre>\t\t\t\t<span class=\"token keyword\">break</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"17\"></td><td><pre>\t\t\t<span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"18\"></td><td><pre>\t\t<span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"19\"></td><td><pre>\t\tarr<span class=\"token punctuation\">[</span>end <span class=\"token operator\">+</span> <span class=\"token number\">1</span><span class=\"token punctuation\">]</span> <span class=\"token operator\">=</span> tmp<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"20\"></td><td><pre>\t<span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"21\"></td><td><pre><span class=\"token punctuation\">&#125;</span></pre></td></tr></table></figure><h5 id=\"稳定性\"><a class=\"anchor\" href=\"#稳定性\">#</a> 稳定性</h5>\n<p>直接插入排序是稳定的。</p>\n<h4 id=\"12-希尔排序shell-sort\"><a class=\"anchor\" href=\"#12-希尔排序shell-sort\">#</a> 1.2 希尔排序 (Shell Sort)</h4>\n<p><img data-src=\"%E5%B8%8C%E5%B0%94%E6%8E%92%E5%BA%8F.gif\" alt=\"希尔排序\" /></p>\n<p>希尔排序是插入排序的一种改进版本，也被称为 “<strong>缩小增量排序</strong>”。其核心思想是将原来要排序的列表分割成多个子序列，先让这些子序列基本有序，再对整个列表进行一次直接插入排序。这样做的目的是让数据移动的次数减少，从而达到减少排序时间的目的。希尔排序的效率比直接插入排序有显著提升。</p>\n<p>希尔排序的步骤：</p>\n<ol>\n<li>选择一个增量，我们先称之为 gap。（比方说对序列 {a<sub>1</sub>,a<sub>2</sub>,a<sub>3</sub>,...,a<sub>n</sub>}，我们可以取<span class=\"katex\"><span class=\"katex-mathml\"><math xmlns=\"http://www.w3.org/1998/Math/MathML\"><semantics><mrow><mi>g</mi><mi>a</mi><mi>p</mi><mo>=</mo><mo stretchy=\"false\">⌊</mo><mi>n</mi><mi mathvariant=\"normal\">/</mi><mn>2</mn><mo stretchy=\"false\">⌋</mo></mrow><annotation encoding=\"application/x-tex\">gap=\\lfloor n/2 \\rfloor</annotation></semantics></math></span><span class=\"katex-html\" aria-hidden=\"true\"><span class=\"base\"><span class=\"strut\" style=\"height:0.625em;vertical-align:-0.19444em;\"></span><span class=\"mord mathnormal\" style=\"margin-right:0.03588em;\">g</span><span class=\"mord mathnormal\">a</span><span class=\"mord mathnormal\">p</span><span class=\"mspace\" style=\"margin-right:0.2777777777777778em;\"></span><span class=\"mrel\">=</span><span class=\"mspace\" style=\"margin-right:0.2777777777777778em;\"></span></span><span class=\"base\"><span class=\"strut\" style=\"height:1em;vertical-align:-0.25em;\"></span><span class=\"mopen\">⌊</span><span class=\"mord mathnormal\">n</span><span class=\"mord\">/</span><span class=\"mord\">2</span><span class=\"mclose\">⌋</span></span></span></span>）</li>\n<li>根据选择的增量序列，将待排序列分成多个子序列，每个子序列包含的元素不连续，但相距等于增量的元素归为同一子序列。（那么原序列就会被分为 n/2 个子序列，包括 {a<sub>1</sub>,a<sub>1+n/2</sub>},{a<sub>2</sub>,a<sub>2+n/2</sub>} 等）</li>\n<li>对每个子序列分别进行直接插入排序。（让分出来的每一个子序列变的有序）</li>\n<li>减小增量再次分组，重复第 3 步，直至增量减至 1，整个序列成为一个子序列，进行最后一次直接插入排序。（比方说第二次增量 gap 取<span class=\"katex\"><span class=\"katex-mathml\"><math xmlns=\"http://www.w3.org/1998/Math/MathML\"><semantics><mrow><mo stretchy=\"false\">⌊</mo><mi>n</mi><mi mathvariant=\"normal\">/</mi><mn>4</mn><mo stretchy=\"false\">⌋</mo></mrow><annotation encoding=\"application/x-tex\">\\lfloor n/4 \\rfloor</annotation></semantics></math></span><span class=\"katex-html\" aria-hidden=\"true\"><span class=\"base\"><span class=\"strut\" style=\"height:1em;vertical-align:-0.25em;\"></span><span class=\"mopen\">⌊</span><span class=\"mord mathnormal\">n</span><span class=\"mord\">/</span><span class=\"mord\">4</span><span class=\"mclose\">⌋</span></span></span></span>，第三次取<span class=\"katex\"><span class=\"katex-mathml\"><math xmlns=\"http://www.w3.org/1998/Math/MathML\"><semantics><mrow><mo stretchy=\"false\">⌊</mo><mi>n</mi><mi mathvariant=\"normal\">/</mi><mn>8</mn><mo stretchy=\"false\">⌋</mo></mrow><annotation encoding=\"application/x-tex\">\\lfloor n/8 \\rfloor</annotation></semantics></math></span><span class=\"katex-html\" aria-hidden=\"true\"><span class=\"base\"><span class=\"strut\" style=\"height:1em;vertical-align:-0.25em;\"></span><span class=\"mopen\">⌊</span><span class=\"mord mathnormal\">n</span><span class=\"mord\">/</span><span class=\"mord\">8</span><span class=\"mclose\">⌋</span></span></span></span>，最后一次则是 gap=1）</li>\n</ol>\n<p>gap 的序列不一定要像我这样取（每次是上一次的一半），但是不<strong>同的增量序列会对这个算法的时间复杂度产生很大的影响</strong>。</p>\n<h5 id=\"时间复杂度-2\"><a class=\"anchor\" href=\"#时间复杂度-2\">#</a> 时间复杂度</h5>\n<p>希尔排序的<strong>时间复杂度计算起来非常困难，或者说数学界都还没有给出一个合适的答案</strong>。</p>\n<p>有人指出当<span class=\"katex\"><span class=\"katex-mathml\"><math xmlns=\"http://www.w3.org/1998/Math/MathML\"><semantics><mrow><mi>g</mi><mi>a</mi><mi>p</mi><mo>=</mo><msup><mn>2</mn><mrow><mi>t</mi><mo>−</mo><mi>k</mi><mo>+</mo><mn>1</mn></mrow></msup><mo>−</mo><mn>1</mn></mrow><annotation encoding=\"application/x-tex\">gap=2^{t-k+1}-1</annotation></semantics></math></span><span class=\"katex-html\" aria-hidden=\"true\"><span class=\"base\"><span class=\"strut\" style=\"height:0.625em;vertical-align:-0.19444em;\"></span><span class=\"mord mathnormal\" style=\"margin-right:0.03588em;\">g</span><span class=\"mord mathnormal\">a</span><span class=\"mord mathnormal\">p</span><span class=\"mspace\" style=\"margin-right:0.2777777777777778em;\"></span><span class=\"mrel\">=</span><span class=\"mspace\" style=\"margin-right:0.2777777777777778em;\"></span></span><span class=\"base\"><span class=\"strut\" style=\"height:0.9324379999999999em;vertical-align:-0.08333em;\"></span><span class=\"mord\"><span class=\"mord\">2</span><span class=\"msupsub\"><span class=\"vlist-t\"><span class=\"vlist-r\"><span class=\"vlist\" style=\"height:0.8491079999999999em;\"><span style=\"top:-3.063em;margin-right:0.05em;\"><span class=\"pstrut\" style=\"height:2.7em;\"></span><span class=\"sizing reset-size6 size3 mtight\"><span class=\"mord mtight\"><span class=\"mord mathnormal mtight\">t</span><span class=\"mbin mtight\">−</span><span class=\"mord mathnormal mtight\" style=\"margin-right:0.03148em;\">k</span><span class=\"mbin mtight\">+</span><span class=\"mord mtight\">1</span></span></span></span></span></span></span></span></span><span class=\"mspace\" style=\"margin-right:0.2222222222222222em;\"></span><span class=\"mbin\">−</span><span class=\"mspace\" style=\"margin-right:0.2222222222222222em;\"></span></span><span class=\"base\"><span class=\"strut\" style=\"height:0.64444em;vertical-align:0em;\"></span><span class=\"mord\">1</span></span></span></span> 时，希尔排序的时间复杂度为<span class=\"katex\"><span class=\"katex-mathml\"><math xmlns=\"http://www.w3.org/1998/Math/MathML\"><semantics><mrow><mi>O</mi><mo stretchy=\"false\">(</mo><msup><mi>n</mi><mrow><mn>3</mn><mi mathvariant=\"normal\">/</mi><mn>2</mn></mrow></msup><mo stretchy=\"false\">)</mo></mrow><annotation encoding=\"application/x-tex\">O(n^{3/2})</annotation></semantics></math></span><span class=\"katex-html\" aria-hidden=\"true\"><span class=\"base\"><span class=\"strut\" style=\"height:1.138em;vertical-align:-0.25em;\"></span><span class=\"mord mathnormal\" style=\"margin-right:0.02778em;\">O</span><span class=\"mopen\">(</span><span class=\"mord\"><span class=\"mord mathnormal\">n</span><span class=\"msupsub\"><span class=\"vlist-t\"><span class=\"vlist-r\"><span class=\"vlist\" style=\"height:0.8879999999999999em;\"><span style=\"top:-3.063em;margin-right:0.05em;\"><span class=\"pstrut\" style=\"height:2.7em;\"></span><span class=\"sizing reset-size6 size3 mtight\"><span class=\"mord mtight\"><span class=\"mord mtight\">3</span><span class=\"mord mtight\">/</span><span class=\"mord mtight\">2</span></span></span></span></span></span></span></span></span><span class=\"mclose\">)</span></span></span></span>，其中<span class=\"katex\"><span class=\"katex-mathml\"><math xmlns=\"http://www.w3.org/1998/Math/MathML\"><semantics><mrow><mi>t</mi></mrow><annotation encoding=\"application/x-tex\">t</annotation></semantics></math></span><span class=\"katex-html\" aria-hidden=\"true\"><span class=\"base\"><span class=\"strut\" style=\"height:0.61508em;vertical-align:0em;\"></span><span class=\"mord mathnormal\">t</span></span></span></span> 是排序次数，<span class=\"katex\"><span class=\"katex-mathml\"><math xmlns=\"http://www.w3.org/1998/Math/MathML\"><semantics><mrow><mn>1</mn><mo>≤</mo><mi>k</mi><mo>≤</mo><mi>t</mi><mo>≤</mo><mo stretchy=\"false\">⌊</mo><msub><mo><mi>log</mi><mo>⁡</mo></mo><mn>2</mn></msub><mo stretchy=\"false\">(</mo><mi>n</mi><mo>+</mo><mn>1</mn><mo stretchy=\"false\">)</mo><mo stretchy=\"false\">⌋</mo></mrow><annotation encoding=\"application/x-tex\">1\\le k\\le t\\le \\lfloor \\log_2 (n+1)\\rfloor</annotation></semantics></math></span><span class=\"katex-html\" aria-hidden=\"true\"><span class=\"base\"><span class=\"strut\" style=\"height:0.78041em;vertical-align:-0.13597em;\"></span><span class=\"mord\">1</span><span class=\"mspace\" style=\"margin-right:0.2777777777777778em;\"></span><span class=\"mrel\">≤</span><span class=\"mspace\" style=\"margin-right:0.2777777777777778em;\"></span></span><span class=\"base\"><span class=\"strut\" style=\"height:0.83041em;vertical-align:-0.13597em;\"></span><span class=\"mord mathnormal\" style=\"margin-right:0.03148em;\">k</span><span class=\"mspace\" style=\"margin-right:0.2777777777777778em;\"></span><span class=\"mrel\">≤</span><span class=\"mspace\" style=\"margin-right:0.2777777777777778em;\"></span></span><span class=\"base\"><span class=\"strut\" style=\"height:0.7719400000000001em;vertical-align:-0.13597em;\"></span><span class=\"mord mathnormal\">t</span><span class=\"mspace\" style=\"margin-right:0.2777777777777778em;\"></span><span class=\"mrel\">≤</span><span class=\"mspace\" style=\"margin-right:0.2777777777777778em;\"></span></span><span class=\"base\"><span class=\"strut\" style=\"height:1em;vertical-align:-0.25em;\"></span><span class=\"mopen\">⌊</span><span class=\"mop\"><span class=\"mop\">lo<span style=\"margin-right:0.01389em;\">g</span></span><span class=\"msupsub\"><span class=\"vlist-t vlist-t2\"><span class=\"vlist-r\"><span class=\"vlist\" style=\"height:0.20696799999999996em;\"><span style=\"top:-2.4558600000000004em;margin-right:0.05em;\"><span class=\"pstrut\" style=\"height:2.7em;\"></span><span class=\"sizing reset-size6 size3 mtight\"><span class=\"mord mtight\">2</span></span></span></span><span class=\"vlist-s\">​</span></span><span class=\"vlist-r\"><span class=\"vlist\" style=\"height:0.24414em;\"><span></span></span></span></span></span></span><span class=\"mopen\">(</span><span class=\"mord mathnormal\">n</span><span class=\"mspace\" style=\"margin-right:0.2222222222222222em;\"></span><span class=\"mbin\">+</span><span class=\"mspace\" style=\"margin-right:0.2222222222222222em;\"></span></span><span class=\"base\"><span class=\"strut\" style=\"height:1em;vertical-align:-0.25em;\"></span><span class=\"mord\">1</span><span class=\"mclose\">)</span><span class=\"mclose\">⌋</span></span></span></span>。</p>\n<p>还有人得出希尔排序在某个范围内比较次数约为 n<sup>1.3</sup>，当 n 趋于正无穷时，可以减少到<span class=\"katex\"><span class=\"katex-mathml\"><math xmlns=\"http://www.w3.org/1998/Math/MathML\"><semantics><mrow><mi>n</mi><mo stretchy=\"false\">(</mo><msub><mo><mi>log</mi><mo>⁡</mo></mo><mn>2</mn></msub><mi>n</mi><msup><mo stretchy=\"false\">)</mo><mn>2</mn></msup></mrow><annotation encoding=\"application/x-tex\">n(\\log_2 n)^2</annotation></semantics></math></span><span class=\"katex-html\" aria-hidden=\"true\"><span class=\"base\"><span class=\"strut\" style=\"height:1.064108em;vertical-align:-0.25em;\"></span><span class=\"mord mathnormal\">n</span><span class=\"mopen\">(</span><span class=\"mop\"><span class=\"mop\">lo<span style=\"margin-right:0.01389em;\">g</span></span><span class=\"msupsub\"><span class=\"vlist-t vlist-t2\"><span class=\"vlist-r\"><span class=\"vlist\" style=\"height:0.20696799999999996em;\"><span style=\"top:-2.4558600000000004em;margin-right:0.05em;\"><span class=\"pstrut\" style=\"height:2.7em;\"></span><span class=\"sizing reset-size6 size3 mtight\"><span class=\"mord mtight\">2</span></span></span></span><span class=\"vlist-s\">​</span></span><span class=\"vlist-r\"><span class=\"vlist\" style=\"height:0.24414em;\"><span></span></span></span></span></span></span><span class=\"mspace\" style=\"margin-right:0.16666666666666666em;\"></span><span class=\"mord mathnormal\">n</span><span class=\"mclose\"><span class=\"mclose\">)</span><span class=\"msupsub\"><span class=\"vlist-t\"><span class=\"vlist-r\"><span class=\"vlist\" style=\"height:0.8141079999999999em;\"><span style=\"top:-3.063em;margin-right:0.05em;\"><span class=\"pstrut\" style=\"height:2.7em;\"></span><span class=\"sizing reset-size6 size3 mtight\"><span class=\"mord mtight\">2</span></span></span></span></span></span></span></span></span></span></span>​​。</p>\n<p>如果我们使用 Knuth 提出的序列，即<span class=\"katex\"><span class=\"katex-mathml\"><math xmlns=\"http://www.w3.org/1998/Math/MathML\"><semantics><mrow><mi>g</mi><mi>a</mi><mi>p</mi><mo>=</mo><mo stretchy=\"false\">⌊</mo><mi>g</mi><mi>a</mi><mi>p</mi><mi mathvariant=\"normal\">/</mi><mn>3</mn><mo stretchy=\"false\">⌋</mo><mo>+</mo><mn>1</mn></mrow><annotation encoding=\"application/x-tex\">gap = \\lfloor gap/3\\rfloor +1</annotation></semantics></math></span><span class=\"katex-html\" aria-hidden=\"true\"><span class=\"base\"><span class=\"strut\" style=\"height:0.625em;vertical-align:-0.19444em;\"></span><span class=\"mord mathnormal\" style=\"margin-right:0.03588em;\">g</span><span class=\"mord mathnormal\">a</span><span class=\"mord mathnormal\">p</span><span class=\"mspace\" style=\"margin-right:0.2777777777777778em;\"></span><span class=\"mrel\">=</span><span class=\"mspace\" style=\"margin-right:0.2777777777777778em;\"></span></span><span class=\"base\"><span class=\"strut\" style=\"height:1em;vertical-align:-0.25em;\"></span><span class=\"mopen\">⌊</span><span class=\"mord mathnormal\" style=\"margin-right:0.03588em;\">g</span><span class=\"mord mathnormal\">a</span><span class=\"mord mathnormal\">p</span><span class=\"mord\">/</span><span class=\"mord\">3</span><span class=\"mclose\">⌋</span><span class=\"mspace\" style=\"margin-right:0.2222222222222222em;\"></span><span class=\"mbin\">+</span><span class=\"mspace\" style=\"margin-right:0.2222222222222222em;\"></span></span><span class=\"base\"><span class=\"strut\" style=\"height:0.64444em;vertical-align:0em;\"></span><span class=\"mord\">1</span></span></span></span>，那么时间复杂度约为<span class=\"katex\"><span class=\"katex-mathml\"><math xmlns=\"http://www.w3.org/1998/Math/MathML\"><semantics><mrow><mi>O</mi><mo stretchy=\"false\">(</mo><msup><mi>N</mi><mn>1.25</mn></msup><mo stretchy=\"false\">)</mo></mrow><annotation encoding=\"application/x-tex\">O(N^{1.25})</annotation></semantics></math></span><span class=\"katex-html\" aria-hidden=\"true\"><span class=\"base\"><span class=\"strut\" style=\"height:1.064108em;vertical-align:-0.25em;\"></span><span class=\"mord mathnormal\" style=\"margin-right:0.02778em;\">O</span><span class=\"mopen\">(</span><span class=\"mord\"><span class=\"mord mathnormal\" style=\"margin-right:0.10903em;\">N</span><span class=\"msupsub\"><span class=\"vlist-t\"><span class=\"vlist-r\"><span class=\"vlist\" style=\"height:0.8141079999999999em;\"><span style=\"top:-3.063em;margin-right:0.05em;\"><span class=\"pstrut\" style=\"height:2.7em;\"></span><span class=\"sizing reset-size6 size3 mtight\"><span class=\"mord mtight\"><span class=\"mord mtight\">1</span><span class=\"mord mtight\">.</span><span class=\"mord mtight\">2</span><span class=\"mord mtight\">5</span></span></span></span></span></span></span></span></span><span class=\"mclose\">)</span></span></span></span>。</p>\n<p>但是我们还是可以知道希尔排序<strong>最坏情况下时间复杂度为</strong><span class=\"katex\"><span class=\"katex-mathml\"><math xmlns=\"http://www.w3.org/1998/Math/MathML\"><semantics><mrow><mi>O</mi><mo stretchy=\"false\">(</mo><msup><mi>N</mi><mn>2</mn></msup><mo stretchy=\"false\">)</mo></mrow><annotation encoding=\"application/x-tex\">O(N^2)</annotation></semantics></math></span><span class=\"katex-html\" aria-hidden=\"true\"><span class=\"base\"><span class=\"strut\" style=\"height:1.064108em;vertical-align:-0.25em;\"></span><span class=\"mord mathnormal\" style=\"margin-right:0.02778em;\">O</span><span class=\"mopen\">(</span><span class=\"mord\"><span class=\"mord mathnormal\" style=\"margin-right:0.10903em;\">N</span><span class=\"msupsub\"><span class=\"vlist-t\"><span class=\"vlist-r\"><span class=\"vlist\" style=\"height:0.8141079999999999em;\"><span style=\"top:-3.063em;margin-right:0.05em;\"><span class=\"pstrut\" style=\"height:2.7em;\"></span><span class=\"sizing reset-size6 size3 mtight\"><span class=\"mord mtight\">2</span></span></span></span></span></span></span></span><span class=\"mclose\">)</span></span></span></span>，<strong>最好情况时间复杂度高于</strong><span class=\"katex\"><span class=\"katex-mathml\"><math xmlns=\"http://www.w3.org/1998/Math/MathML\"><semantics><mrow><mi>O</mi><mo stretchy=\"false\">(</mo><mi>N</mi><mi>log</mi><mo>⁡</mo><mi>N</mi><mo stretchy=\"false\">)</mo></mrow><annotation encoding=\"application/x-tex\">O(N\\log N)</annotation></semantics></math></span><span class=\"katex-html\" aria-hidden=\"true\"><span class=\"base\"><span class=\"strut\" style=\"height:1em;vertical-align:-0.25em;\"></span><span class=\"mord mathnormal\" style=\"margin-right:0.02778em;\">O</span><span class=\"mopen\">(</span><span class=\"mord mathnormal\" style=\"margin-right:0.10903em;\">N</span><span class=\"mspace\" style=\"margin-right:0.16666666666666666em;\"></span><span class=\"mop\">lo<span style=\"margin-right:0.01389em;\">g</span></span><span class=\"mspace\" style=\"margin-right:0.16666666666666666em;\"></span><span class=\"mord mathnormal\" style=\"margin-right:0.10903em;\">N</span><span class=\"mclose\">)</span></span></span></span>，<strong>一般情况下都远优于时间复杂度为</strong><span class=\"katex\"><span class=\"katex-mathml\"><math xmlns=\"http://www.w3.org/1998/Math/MathML\"><semantics><mrow><mi>O</mi><mo stretchy=\"false\">(</mo><msup><mi>N</mi><mn>2</mn></msup><mo stretchy=\"false\">)</mo></mrow><annotation encoding=\"application/x-tex\">O(N^2)</annotation></semantics></math></span><span class=\"katex-html\" aria-hidden=\"true\"><span class=\"base\"><span class=\"strut\" style=\"height:1.064108em;vertical-align:-0.25em;\"></span><span class=\"mord mathnormal\" style=\"margin-right:0.02778em;\">O</span><span class=\"mopen\">(</span><span class=\"mord\"><span class=\"mord mathnormal\" style=\"margin-right:0.10903em;\">N</span><span class=\"msupsub\"><span class=\"vlist-t\"><span class=\"vlist-r\"><span class=\"vlist\" style=\"height:0.8141079999999999em;\"><span style=\"top:-3.063em;margin-right:0.05em;\"><span class=\"pstrut\" style=\"height:2.7em;\"></span><span class=\"sizing reset-size6 size3 mtight\"><span class=\"mord mtight\">2</span></span></span></span></span></span></span></span><span class=\"mclose\">)</span></span></span></span>​<strong>的算法</strong>。</p>\n<h5 id=\"实现-2\"><a class=\"anchor\" href=\"#实现-2\">#</a> 实现</h5>\n<figure class=\"highlight c\"><figcaption data-lang=\"c\"><span>取gap为gap/2 希尔排序</span></figcaption><table><tr><td data-num=\"1\"></td><td><pre><span class=\"token keyword\">void</span> <span class=\"token function\">ShellSort</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">int</span><span class=\"token operator\">*</span> arr<span class=\"token punctuation\">,</span> <span class=\"token keyword\">int</span> n<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"2\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"3\"></td><td><pre>\t<span class=\"token keyword\">int</span> gap <span class=\"token operator\">=</span> n<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"4\"></td><td><pre>\t<span class=\"token keyword\">while</span> <span class=\"token punctuation\">(</span>gap <span class=\"token operator\">></span> <span class=\"token number\">1</span><span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"5\"></td><td><pre>\t<span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"6\"></td><td><pre>\t\tgap <span class=\"token operator\">/=</span> <span class=\"token number\">2</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"7\"></td><td><pre>\t\t<span class=\"token keyword\">for</span> <span class=\"token punctuation\">(</span><span class=\"token keyword\">int</span> i <span class=\"token operator\">=</span> <span class=\"token number\">0</span><span class=\"token punctuation\">;</span> i <span class=\"token operator\">&lt;</span> n <span class=\"token operator\">-</span> gap<span class=\"token punctuation\">;</span> <span class=\"token operator\">++</span>i<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"8\"></td><td><pre>\t\t<span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"9\"></td><td><pre>\t\t\t<span class=\"token keyword\">int</span> end <span class=\"token operator\">=</span> i<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"10\"></td><td><pre>\t\t\t<span class=\"token keyword\">int</span> tmp <span class=\"token operator\">=</span> arr<span class=\"token punctuation\">[</span>end <span class=\"token operator\">+</span> gap<span class=\"token punctuation\">]</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"11\"></td><td><pre>\t\t\t<span class=\"token keyword\">while</span> <span class=\"token punctuation\">(</span>end <span class=\"token operator\">>=</span> <span class=\"token number\">0</span><span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"12\"></td><td><pre>\t\t\t<span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"13\"></td><td><pre>\t\t\t\t<span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>tmp <span class=\"token operator\">&lt;</span> arr<span class=\"token punctuation\">[</span>end<span class=\"token punctuation\">]</span><span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"14\"></td><td><pre>\t\t\t\t<span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"15\"></td><td><pre>\t\t\t\t\tarr<span class=\"token punctuation\">[</span>end <span class=\"token operator\">+</span> gap<span class=\"token punctuation\">]</span> <span class=\"token operator\">=</span> arr<span class=\"token punctuation\">[</span>end<span class=\"token punctuation\">]</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"16\"></td><td><pre>\t\t\t\t\tend <span class=\"token operator\">-=</span> gap<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"17\"></td><td><pre>\t\t\t\t<span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"18\"></td><td><pre>\t\t\t\t<span class=\"token keyword\">else</span></pre></td></tr><tr><td data-num=\"19\"></td><td><pre>\t\t\t\t<span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"20\"></td><td><pre>\t\t\t\t\t<span class=\"token keyword\">break</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"21\"></td><td><pre>\t\t\t\t<span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"22\"></td><td><pre>\t\t\t<span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"23\"></td><td><pre>\t\t\tarr<span class=\"token punctuation\">[</span>end <span class=\"token operator\">+</span> gap<span class=\"token punctuation\">]</span> <span class=\"token operator\">=</span> tmp<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"24\"></td><td><pre>\t\t<span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"25\"></td><td><pre>\t<span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"26\"></td><td><pre><span class=\"token punctuation\">&#125;</span></pre></td></tr></table></figure><h5 id=\"稳定性-2\"><a class=\"anchor\" href=\"#稳定性-2\">#</a> 稳定性</h5>\n<p>希尔排序是不稳定的。</p>\n<h3 id=\"二-选择排序\"><a class=\"anchor\" href=\"#二-选择排序\">#</a> 二、选择排序</h3>\n<h4 id=\"21-直接选择排序\"><a class=\"anchor\" href=\"#21-直接选择排序\">#</a> 2.1 直接选择排序</h4>\n<p><img data-src=\"%E9%80%89%E6%8B%A9%E6%8E%92%E5%BA%8F.gif\" alt=\"选择排序\" /></p>\n<p>直接选择排序是一种简单直观的排序算法。简单说就是在一堆数中，一次次从头到尾挑出最小的数，然后依次排列起来。</p>\n<p>直接选择排序的步骤：</p>\n<ol>\n<li>在未排序序列中找到最小（最大）元素，存放到排序序列的起始位置。</li>\n<li>再从剩余未排序元素中继续寻找最小（最大）元素，然后放到已排序序列的末尾。</li>\n<li>重复第二步，直到所有元素均排序完毕。</li>\n</ol>\n<h5 id=\"时间复杂度-3\"><a class=\"anchor\" href=\"#时间复杂度-3\">#</a> 时间复杂度</h5>\n<p>时间复杂度为<span class=\"katex\"><span class=\"katex-mathml\"><math xmlns=\"http://www.w3.org/1998/Math/MathML\"><semantics><mrow><mi>O</mi><mo stretchy=\"false\">(</mo><msup><mi>N</mi><mn>2</mn></msup><mo stretchy=\"false\">)</mo></mrow><annotation encoding=\"application/x-tex\">O(N^2)</annotation></semantics></math></span><span class=\"katex-html\" aria-hidden=\"true\"><span class=\"base\"><span class=\"strut\" style=\"height:1.064108em;vertical-align:-0.25em;\"></span><span class=\"mord mathnormal\" style=\"margin-right:0.02778em;\">O</span><span class=\"mopen\">(</span><span class=\"mord\"><span class=\"mord mathnormal\" style=\"margin-right:0.10903em;\">N</span><span class=\"msupsub\"><span class=\"vlist-t\"><span class=\"vlist-r\"><span class=\"vlist\" style=\"height:0.8141079999999999em;\"><span style=\"top:-3.063em;margin-right:0.05em;\"><span class=\"pstrut\" style=\"height:2.7em;\"></span><span class=\"sizing reset-size6 size3 mtight\"><span class=\"mord mtight\">2</span></span></span></span></span></span></span></span><span class=\"mclose\">)</span></span></span></span>​，没有最好最坏的说法，效率不高。</p>\n<h5 id=\"实现-3\"><a class=\"anchor\" href=\"#实现-3\">#</a> 实现</h5>\n<figure class=\"highlight c\"><figcaption data-lang=\"c\"><span>直接选择排序</span></figcaption><table><tr><td data-num=\"1\"></td><td><pre><span class=\"token keyword\">void</span> <span class=\"token function\">SelectSort</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">int</span><span class=\"token operator\">*</span> arr<span class=\"token punctuation\">,</span> <span class=\"token keyword\">int</span> n<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"2\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"3\"></td><td><pre>\t<span class=\"token keyword\">for</span> <span class=\"token punctuation\">(</span><span class=\"token keyword\">int</span> i <span class=\"token operator\">=</span> <span class=\"token number\">0</span><span class=\"token punctuation\">;</span> i <span class=\"token operator\">&lt;</span> n <span class=\"token operator\">-</span> <span class=\"token number\">1</span><span class=\"token punctuation\">;</span> <span class=\"token operator\">++</span>i<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"4\"></td><td><pre>\t<span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"5\"></td><td><pre>\t\t<span class=\"token keyword\">int</span> min <span class=\"token operator\">=</span> i<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"6\"></td><td><pre>\t\t<span class=\"token keyword\">for</span> <span class=\"token punctuation\">(</span><span class=\"token keyword\">int</span> j <span class=\"token operator\">=</span> i <span class=\"token operator\">+</span> <span class=\"token number\">1</span><span class=\"token punctuation\">;</span> j <span class=\"token operator\">&lt;</span> n<span class=\"token punctuation\">;</span> <span class=\"token operator\">++</span>j<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"7\"></td><td><pre>\t\t<span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"8\"></td><td><pre>\t\t\t<span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>arr<span class=\"token punctuation\">[</span>j<span class=\"token punctuation\">]</span> <span class=\"token operator\">&lt;</span> arr<span class=\"token punctuation\">[</span>min<span class=\"token punctuation\">]</span><span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"9\"></td><td><pre>\t\t\t<span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"10\"></td><td><pre>\t\t\t\tmin <span class=\"token operator\">=</span> j<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"11\"></td><td><pre>\t\t\t<span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"12\"></td><td><pre>\t\t<span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"13\"></td><td><pre>\t\t<span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>min <span class=\"token operator\">!=</span> i<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"14\"></td><td><pre>\t\t<span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"15\"></td><td><pre>\t\t\t<span class=\"token function\">Swap</span><span class=\"token punctuation\">(</span><span class=\"token operator\">&amp;</span>arr<span class=\"token punctuation\">[</span>i<span class=\"token punctuation\">]</span><span class=\"token punctuation\">,</span> <span class=\"token operator\">&amp;</span>arr<span class=\"token punctuation\">[</span>min<span class=\"token punctuation\">]</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"16\"></td><td><pre>\t\t<span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"17\"></td><td><pre>\t<span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"18\"></td><td><pre><span class=\"token punctuation\">&#125;</span></pre></td></tr></table></figure><h5 id=\"稳定性-3\"><a class=\"anchor\" href=\"#稳定性-3\">#</a> 稳定性</h5>\n<p>直接选择排序是不稳定的。</p>\n<h4 id=\"22-堆排序\"><a class=\"anchor\" href=\"#22-堆排序\">#</a> 2.2 堆排序</h4>\n<p><img data-src=\"%E5%A0%86%E6%8E%92%E5%BA%8F.gif\" alt=\"堆排序\" /></p>\n<p>堆排序算法是<strong>利用大堆（或小堆）的性质</strong>来对数组进行排序的，相关内容在前几篇笔记已详细介绍。</p>\n<p>堆排序的步骤：</p>\n<ol>\n<li><strong>建立堆：</strong> 将给定的无序数组构造成一个最大堆（为了升序排序）或最小堆（为了降序排序）。这个过程是通过将数组视为二叉树，然后从最后一个非叶子节点开始，向上调整每个节点，确保每个节点都遵循堆的性质，即每个父节点的值都大于其子节点的值（最大堆）或每个父节点的值都小于其子节点的值（最小堆）。</li>\n<li><strong>堆排序：</strong> 由于堆的根节点表示最大（或最小）元素，可以将其与堆的最后一个元素交换，然后将剩下的元素重新调整为最大（或最小）堆。重复这个过程，直到所有元素都被排序。</li>\n</ol>\n<h5 id=\"时间复杂度-4\"><a class=\"anchor\" href=\"#时间复杂度-4\">#</a> 时间复杂度</h5>\n<p>堆排序的效率非常高，时间复杂度为<span class=\"katex\"><span class=\"katex-mathml\"><math xmlns=\"http://www.w3.org/1998/Math/MathML\"><semantics><mrow><mi>O</mi><mo stretchy=\"false\">(</mo><mi>N</mi><mi>log</mi><mo>⁡</mo><mi>N</mi><mo stretchy=\"false\">)</mo></mrow><annotation encoding=\"application/x-tex\">O(N\\log N)</annotation></semantics></math></span><span class=\"katex-html\" aria-hidden=\"true\"><span class=\"base\"><span class=\"strut\" style=\"height:1em;vertical-align:-0.25em;\"></span><span class=\"mord mathnormal\" style=\"margin-right:0.02778em;\">O</span><span class=\"mopen\">(</span><span class=\"mord mathnormal\" style=\"margin-right:0.10903em;\">N</span><span class=\"mspace\" style=\"margin-right:0.16666666666666666em;\"></span><span class=\"mop\">lo<span style=\"margin-right:0.01389em;\">g</span></span><span class=\"mspace\" style=\"margin-right:0.16666666666666666em;\"></span><span class=\"mord mathnormal\" style=\"margin-right:0.10903em;\">N</span><span class=\"mclose\">)</span></span></span></span>​​。</p>\n<h5 id=\"实现-4\"><a class=\"anchor\" href=\"#实现-4\">#</a> 实现</h5>\n<figure class=\"highlight c\"><figcaption data-lang=\"c\"><span>堆排序</span></figcaption><table><tr><td data-num=\"1\"></td><td><pre><span class=\"token keyword\">void</span> <span class=\"token function\">AdjustDown</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">int</span><span class=\"token operator\">*</span> arr<span class=\"token punctuation\">,</span> <span class=\"token keyword\">int</span> n<span class=\"token punctuation\">,</span> <span class=\"token keyword\">int</span> parent<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"2\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"3\"></td><td><pre>\t<span class=\"token keyword\">int</span> child <span class=\"token operator\">=</span> parent <span class=\"token operator\">*</span> <span class=\"token number\">2</span> <span class=\"token operator\">+</span> <span class=\"token number\">1</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"4\"></td><td><pre>\t<span class=\"token keyword\">while</span> <span class=\"token punctuation\">(</span>child <span class=\"token operator\">&lt;</span> n<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"5\"></td><td><pre>\t<span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"6\"></td><td><pre>\t\t<span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>child <span class=\"token operator\">+</span> <span class=\"token number\">1</span> <span class=\"token operator\">&lt;</span> n <span class=\"token operator\">&amp;&amp;</span> arr<span class=\"token punctuation\">[</span>child <span class=\"token operator\">+</span> <span class=\"token number\">1</span><span class=\"token punctuation\">]</span> <span class=\"token operator\">></span> arr<span class=\"token punctuation\">[</span>child<span class=\"token punctuation\">]</span><span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"7\"></td><td><pre>\t\t<span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"8\"></td><td><pre>\t\t\t<span class=\"token operator\">++</span>child<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"9\"></td><td><pre>\t\t<span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"10\"></td><td><pre>\t\t<span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>arr<span class=\"token punctuation\">[</span>child<span class=\"token punctuation\">]</span> <span class=\"token operator\">></span> arr<span class=\"token punctuation\">[</span>parent<span class=\"token punctuation\">]</span><span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"11\"></td><td><pre>\t\t<span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"12\"></td><td><pre>\t\t\t<span class=\"token function\">Swap</span><span class=\"token punctuation\">(</span><span class=\"token operator\">&amp;</span>arr<span class=\"token punctuation\">[</span>child<span class=\"token punctuation\">]</span><span class=\"token punctuation\">,</span> <span class=\"token operator\">&amp;</span>arr<span class=\"token punctuation\">[</span>parent<span class=\"token punctuation\">]</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"13\"></td><td><pre>\t\t\tparent <span class=\"token operator\">=</span> child<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"14\"></td><td><pre>\t\t\tchild <span class=\"token operator\">=</span> parent <span class=\"token operator\">*</span> <span class=\"token number\">2</span> <span class=\"token operator\">+</span> <span class=\"token number\">1</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"15\"></td><td><pre>\t\t<span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"16\"></td><td><pre>\t\t<span class=\"token keyword\">else</span></pre></td></tr><tr><td data-num=\"17\"></td><td><pre>\t\t<span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"18\"></td><td><pre>\t\t\t<span class=\"token keyword\">break</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"19\"></td><td><pre>\t\t<span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"20\"></td><td><pre>\t<span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"21\"></td><td><pre><span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"22\"></td><td><pre><span class=\"token keyword\">void</span> <span class=\"token function\">HeapSort</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">int</span><span class=\"token operator\">*</span> arr<span class=\"token punctuation\">,</span> <span class=\"token keyword\">int</span> n<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"23\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"24\"></td><td><pre>\t<span class=\"token keyword\">for</span> <span class=\"token punctuation\">(</span><span class=\"token keyword\">int</span> i <span class=\"token operator\">=</span> n <span class=\"token operator\">/</span> <span class=\"token number\">2</span> <span class=\"token operator\">-</span> <span class=\"token number\">1</span><span class=\"token punctuation\">;</span> i <span class=\"token operator\">>=</span> <span class=\"token number\">0</span><span class=\"token punctuation\">;</span> <span class=\"token operator\">--</span>i<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"25\"></td><td><pre>\t<span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"26\"></td><td><pre>\t\t<span class=\"token function\">AdjustDown</span><span class=\"token punctuation\">(</span>arr<span class=\"token punctuation\">,</span> n<span class=\"token punctuation\">,</span> i<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"27\"></td><td><pre>\t<span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"28\"></td><td><pre>\t<span class=\"token keyword\">int</span> end <span class=\"token operator\">=</span> n <span class=\"token operator\">-</span> <span class=\"token number\">1</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"29\"></td><td><pre>\t<span class=\"token keyword\">while</span> <span class=\"token punctuation\">(</span>end <span class=\"token operator\">></span> <span class=\"token number\">0</span><span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"30\"></td><td><pre>\t<span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"31\"></td><td><pre>\t\t<span class=\"token function\">Swap</span><span class=\"token punctuation\">(</span><span class=\"token operator\">&amp;</span>arr<span class=\"token punctuation\">[</span><span class=\"token number\">0</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">,</span> <span class=\"token operator\">&amp;</span>arr<span class=\"token punctuation\">[</span>end<span class=\"token punctuation\">]</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"32\"></td><td><pre>\t\t<span class=\"token function\">AdjustDown</span><span class=\"token punctuation\">(</span>arr<span class=\"token punctuation\">,</span> end<span class=\"token punctuation\">,</span> <span class=\"token number\">0</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"33\"></td><td><pre>\t\t<span class=\"token operator\">--</span>end<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"34\"></td><td><pre>\t<span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"35\"></td><td><pre><span class=\"token punctuation\">&#125;</span></pre></td></tr></table></figure><h5 id=\"稳定性-4\"><a class=\"anchor\" href=\"#稳定性-4\">#</a> 稳定性</h5>\n<p>堆排序是不稳定的。</p>\n<h3 id=\"三-交换排序\"><a class=\"anchor\" href=\"#三-交换排序\">#</a> 三、交换排序</h3>\n<h4 id=\"31-冒泡排序\"><a class=\"anchor\" href=\"#31-冒泡排序\">#</a> 3.1 冒泡排序</h4>\n<p><img data-src=\"%E5%86%92%E6%B3%A1%E6%8E%92%E5%BA%8F.gif\" alt=\"冒泡排序\" /></p>\n<p>冒泡排序是我们的老熟人了，是一种简单的排序算法，重复的遍历要排序的数列，一次比较两个元素，如果它们的顺序错误就把它们交换过来。越小（或越大）的元素会经过交换慢慢 “浮” 到数列的顶端，因此称为冒泡排序。</p>\n<p>冒泡排序的步骤如下：</p>\n<ol>\n<li>比较相邻的元素。如果第一个比第二个大（升序），就交换它们两个。</li>\n<li>对每一对相邻元素做同样的工作，从开始第一对到结尾的最后一对。这步做完后，最后的元素会是最大的数。</li>\n<li>针对所有的元素重复以上的步骤，除了最后一个。</li>\n<li>持续每次对越来越少的元素重复上面的步骤，直到没有任何一对数字需要比较。</li>\n</ol>\n<h5 id=\"时间复杂度-5\"><a class=\"anchor\" href=\"#时间复杂度-5\">#</a> 时间复杂度</h5>\n<p>时间复杂度为<span class=\"katex\"><span class=\"katex-mathml\"><math xmlns=\"http://www.w3.org/1998/Math/MathML\"><semantics><mrow><mi>O</mi><mo stretchy=\"false\">(</mo><msup><mi>N</mi><mn>2</mn></msup><mo stretchy=\"false\">)</mo></mrow><annotation encoding=\"application/x-tex\">O(N^2)</annotation></semantics></math></span><span class=\"katex-html\" aria-hidden=\"true\"><span class=\"base\"><span class=\"strut\" style=\"height:1.064108em;vertical-align:-0.25em;\"></span><span class=\"mord mathnormal\" style=\"margin-right:0.02778em;\">O</span><span class=\"mopen\">(</span><span class=\"mord\"><span class=\"mord mathnormal\" style=\"margin-right:0.10903em;\">N</span><span class=\"msupsub\"><span class=\"vlist-t\"><span class=\"vlist-r\"><span class=\"vlist\" style=\"height:0.8141079999999999em;\"><span style=\"top:-3.063em;margin-right:0.05em;\"><span class=\"pstrut\" style=\"height:2.7em;\"></span><span class=\"sizing reset-size6 size3 mtight\"><span class=\"mord mtight\">2</span></span></span></span></span></span></span></span><span class=\"mclose\">)</span></span></span></span>，而且大 O 表示法省略的常数不小，<mark>效率相当低</mark>。</p>\n<h5 id=\"实现-5\"><a class=\"anchor\" href=\"#实现-5\">#</a> 实现</h5>\n<figure class=\"highlight c\"><figcaption data-lang=\"c\"><span>冒泡排序</span></figcaption><table><tr><td data-num=\"1\"></td><td><pre><span class=\"token keyword\">void</span> <span class=\"token function\">BubbleSort</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">int</span><span class=\"token operator\">*</span> arr<span class=\"token punctuation\">,</span> <span class=\"token keyword\">int</span> n<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"2\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"3\"></td><td><pre>\t<span class=\"token keyword\">for</span> <span class=\"token punctuation\">(</span><span class=\"token keyword\">int</span> i <span class=\"token operator\">=</span> <span class=\"token number\">0</span><span class=\"token punctuation\">;</span> i <span class=\"token operator\">&lt;</span> n <span class=\"token operator\">-</span> <span class=\"token number\">1</span><span class=\"token punctuation\">;</span> <span class=\"token operator\">++</span>i<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"4\"></td><td><pre>\t<span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"5\"></td><td><pre>\t\t<span class=\"token keyword\">int</span> flag <span class=\"token operator\">=</span> <span class=\"token number\">0</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"6\"></td><td><pre>\t\t<span class=\"token keyword\">for</span> <span class=\"token punctuation\">(</span><span class=\"token keyword\">int</span> j <span class=\"token operator\">=</span> <span class=\"token number\">0</span><span class=\"token punctuation\">;</span> j <span class=\"token operator\">&lt;</span> n <span class=\"token operator\">-</span> i <span class=\"token operator\">-</span> <span class=\"token number\">1</span><span class=\"token punctuation\">;</span> <span class=\"token operator\">++</span>j<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"7\"></td><td><pre>\t\t<span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"8\"></td><td><pre>\t\t\t<span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>arr<span class=\"token punctuation\">[</span>j<span class=\"token punctuation\">]</span> <span class=\"token operator\">></span> arr<span class=\"token punctuation\">[</span>j <span class=\"token operator\">+</span> <span class=\"token number\">1</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"9\"></td><td><pre>\t\t\t<span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"10\"></td><td><pre>\t\t\t\t<span class=\"token function\">Swap</span><span class=\"token punctuation\">(</span><span class=\"token operator\">&amp;</span>arr<span class=\"token punctuation\">[</span>j<span class=\"token punctuation\">]</span><span class=\"token punctuation\">,</span> <span class=\"token operator\">&amp;</span>arr<span class=\"token punctuation\">[</span>j <span class=\"token operator\">+</span> <span class=\"token number\">1</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"11\"></td><td><pre>\t\t\t\tflag <span class=\"token operator\">=</span> <span class=\"token number\">1</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"12\"></td><td><pre>\t\t\t<span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"13\"></td><td><pre>\t\t<span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"14\"></td><td><pre>\t\t<span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>flag <span class=\"token operator\">==</span> <span class=\"token number\">0</span><span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"15\"></td><td><pre>\t\t<span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"16\"></td><td><pre>\t\t\t<span class=\"token keyword\">break</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"17\"></td><td><pre>\t\t<span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"18\"></td><td><pre>\t<span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"19\"></td><td><pre><span class=\"token punctuation\">&#125;</span></pre></td></tr></table></figure><h5 id=\"稳定性-5\"><a class=\"anchor\" href=\"#稳定性-5\">#</a> 稳定性</h5>\n<p>冒泡排序是稳定的。</p>\n<h4 id=\"32-快速排序\"><a class=\"anchor\" href=\"#32-快速排序\">#</a> 3.2 快速排序</h4>\n<p>快速排序是一种非常高效的排序，基本思想是 ==“分而治之”==（将一个大问题分解成小问题）。</p>\n<p>快速排序的核心是选择一个 “基准值”，然后将数组分为两部分：一部分包含小于基准值的元素，另一部分包含大于基准值的元素。通过递归不断对这两部分继续进行分区，直到整个序列有序。</p>\n<p>快速排序的步骤如下：</p>\n<ol>\n<li><strong>选择基准值</strong>：从数列中挑出一个元素，称为 “基准”。</li>\n<li><strong>分区操作</strong>：重新排列数列，所有比基准值小的元素摆放在基准前面，所有比基准值大的元素摆在基准的后面（相同的数可以到任一边）。在这个分区退出之后，基准就处于数列的中间位置。</li>\n<li><strong>递归排序</strong>：递归将小于基准值的子数列和大于基准值的子数列重复前俩步来实现排序。</li>\n</ol>\n<h5 id=\"时间复杂度-6\"><a class=\"anchor\" href=\"#时间复杂度-6\">#</a> 时间复杂度</h5>\n<p>快速排序的效率非常高，平均时间复杂度为<span class=\"katex\"><span class=\"katex-mathml\"><math xmlns=\"http://www.w3.org/1998/Math/MathML\"><semantics><mrow><mi>O</mi><mo stretchy=\"false\">(</mo><mi>N</mi><mi>log</mi><mo>⁡</mo><mtext> </mtext><mi>N</mi><mo stretchy=\"false\">)</mo></mrow><annotation encoding=\"application/x-tex\">O(N\\log\\,N)</annotation></semantics></math></span><span class=\"katex-html\" aria-hidden=\"true\"><span class=\"base\"><span class=\"strut\" style=\"height:1em;vertical-align:-0.25em;\"></span><span class=\"mord mathnormal\" style=\"margin-right:0.02778em;\">O</span><span class=\"mopen\">(</span><span class=\"mord mathnormal\" style=\"margin-right:0.10903em;\">N</span><span class=\"mspace\" style=\"margin-right:0.16666666666666666em;\"></span><span class=\"mop\">lo<span style=\"margin-right:0.01389em;\">g</span></span><span class=\"mspace\" style=\"margin-right:0.16666666666666666em;\"></span><span class=\"mspace\" style=\"margin-right:0.16666666666666666em;\"></span><span class=\"mord mathnormal\" style=\"margin-right:0.10903em;\">N</span><span class=\"mclose\">)</span></span></span></span>，但最坏情况下会退化到<span class=\"katex\"><span class=\"katex-mathml\"><math xmlns=\"http://www.w3.org/1998/Math/MathML\"><semantics><mrow><mi>O</mi><mo stretchy=\"false\">(</mo><msup><mi>N</mi><mn>2</mn></msup><mo stretchy=\"false\">)</mo></mrow><annotation encoding=\"application/x-tex\">O(N^{2})</annotation></semantics></math></span><span class=\"katex-html\" aria-hidden=\"true\"><span class=\"base\"><span class=\"strut\" style=\"height:1.064108em;vertical-align:-0.25em;\"></span><span class=\"mord mathnormal\" style=\"margin-right:0.02778em;\">O</span><span class=\"mopen\">(</span><span class=\"mord\"><span class=\"mord mathnormal\" style=\"margin-right:0.10903em;\">N</span><span class=\"msupsub\"><span class=\"vlist-t\"><span class=\"vlist-r\"><span class=\"vlist\" style=\"height:0.8141079999999999em;\"><span style=\"top:-3.063em;margin-right:0.05em;\"><span class=\"pstrut\" style=\"height:2.7em;\"></span><span class=\"sizing reset-size6 size3 mtight\"><span class=\"mord mtight\"><span class=\"mord mtight\">2</span></span></span></span></span></span></span></span></span><span class=\"mclose\">)</span></span></span></span>。</p>\n<p>但是非常神奇，这个最坏情况与其他排序不同，是在原数组<mark>有序或者接近有序</mark>的情况下为最坏情况。（<mark>越乱排序越快</mark>）</p>\n<p>但是我们可以通过一些技巧来避免快速排序会取到最坏情况这件事，这会在下面介绍。</p>\n<h5 id=\"实现-6\"><a class=\"anchor\" href=\"#实现-6\">#</a> 实现</h5>\n<h6 id=\"原始的快速排序-hoare法\"><a class=\"anchor\" href=\"#原始的快速排序-hoare法\">#</a> 原始的快速排序 - Hoare 法</h6>\n<p><img data-src=\"hoare.gif\" alt=\"Hoare快排\" /></p>\n<p>这是 Hoare 大佬刚提出快速排序时给出的方法。</p>\n<p>我们记录排序区间的左下标 left 和右下标 right，并选取基准值 key 的下标（这边我们以 key=left 为例，若选择 key=right 下面反过来想就能得出）。我们使 right 从右往左跑直到找到小于基准值或者遇到 left，然后我们让 left 从左往右跑直到找到大于基准值或者遇到 right，随后交换 left 和 right 标记的值。重复这个过程就能完成一次分区，随后再写入递归即可完成排序。</p>\n<figure class=\"highlight c\"><figcaption data-lang=\"c\"><span>快速排序 hoare法</span></figcaption><table><tr><td data-num=\"1\"></td><td><pre><span class=\"token keyword\">void</span> <span class=\"token function\">QuickSort</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">int</span><span class=\"token operator\">*</span> arr<span class=\"token punctuation\">,</span> <span class=\"token keyword\">int</span> left<span class=\"token punctuation\">,</span> <span class=\"token keyword\">int</span> right<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"2\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"3\"></td><td><pre>\t<span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>left <span class=\"token operator\">>=</span> right<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"4\"></td><td><pre>\t<span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"5\"></td><td><pre>\t\t<span class=\"token keyword\">return</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"6\"></td><td><pre>\t<span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"7\"></td><td><pre>\t<span class=\"token keyword\">int</span> key <span class=\"token operator\">=</span> left<span class=\"token punctuation\">,</span> begin <span class=\"token operator\">=</span> left<span class=\"token punctuation\">,</span> end <span class=\"token operator\">=</span> right<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"8\"></td><td><pre>\t<span class=\"token keyword\">while</span> <span class=\"token punctuation\">(</span>left <span class=\"token operator\">&lt;</span> right<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"9\"></td><td><pre>\t<span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"10\"></td><td><pre>\t\t<span class=\"token keyword\">while</span> <span class=\"token punctuation\">(</span>left <span class=\"token operator\">&lt;</span> right <span class=\"token operator\">&amp;&amp;</span> arr<span class=\"token punctuation\">[</span>right<span class=\"token punctuation\">]</span> <span class=\"token operator\">>=</span> arr<span class=\"token punctuation\">[</span>key<span class=\"token punctuation\">]</span><span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"11\"></td><td><pre>\t\t<span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"12\"></td><td><pre>\t\t\t<span class=\"token operator\">--</span>right<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"13\"></td><td><pre>\t\t<span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"14\"></td><td><pre>\t\t<span class=\"token keyword\">while</span> <span class=\"token punctuation\">(</span>left <span class=\"token operator\">&lt;</span> right <span class=\"token operator\">&amp;&amp;</span> arr<span class=\"token punctuation\">[</span>left<span class=\"token punctuation\">]</span> <span class=\"token operator\">&lt;=</span> arr<span class=\"token punctuation\">[</span>key<span class=\"token punctuation\">]</span><span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"15\"></td><td><pre>\t\t<span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"16\"></td><td><pre>\t\t\t<span class=\"token operator\">++</span>left<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"17\"></td><td><pre>\t\t<span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"18\"></td><td><pre>\t\t<span class=\"token function\">Swap</span><span class=\"token punctuation\">(</span><span class=\"token operator\">&amp;</span>arr<span class=\"token punctuation\">[</span>left<span class=\"token punctuation\">]</span><span class=\"token punctuation\">,</span> <span class=\"token operator\">&amp;</span>arr<span class=\"token punctuation\">[</span>right<span class=\"token punctuation\">]</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"19\"></td><td><pre>\t<span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"20\"></td><td><pre>\t<span class=\"token function\">Swap</span><span class=\"token punctuation\">(</span><span class=\"token operator\">&amp;</span>arr<span class=\"token punctuation\">[</span>left<span class=\"token punctuation\">]</span><span class=\"token punctuation\">,</span> <span class=\"token operator\">&amp;</span>arr<span class=\"token punctuation\">[</span>key<span class=\"token punctuation\">]</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"21\"></td><td><pre>\t<span class=\"token function\">QuickSort</span><span class=\"token punctuation\">(</span>arr<span class=\"token punctuation\">,</span> begin<span class=\"token punctuation\">,</span> left <span class=\"token operator\">-</span> <span class=\"token number\">1</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"22\"></td><td><pre>\t<span class=\"token function\">QuickSort</span><span class=\"token punctuation\">(</span>arr<span class=\"token punctuation\">,</span> left <span class=\"token operator\">+</span> <span class=\"token number\">1</span><span class=\"token punctuation\">,</span> end<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"23\"></td><td><pre><span class=\"token punctuation\">&#125;</span></pre></td></tr></table></figure><h6 id=\"逻辑简洁的快速排序-挖坑法\"><a class=\"anchor\" href=\"#逻辑简洁的快速排序-挖坑法\">#</a> 逻辑简洁的快速排序 - 挖坑法</h6>\n<p><img data-src=\"dighole.gif\" alt=\"挖坑法\" /></p>\n<p>挖坑法在逻辑上更易于理解，<strong>不会陷入为什么左右标记不会越过对方、为什么一定要先移动某个标记等问题</strong>。</p>\n<p>挖坑法就是把基准值单独复制出来放到一个变量里，原本的位置作为一个 “<mark>坑位</mark>”（还是假设 key=left）。然后右标记左移直到发现小于基准值的数，把这个数 “挖出来” 填到 “坑位” 里。这个时候挖走的形成了一个新的坑位，这时左标记右移直到找到大于基准值的数，再次挖到 “坑位” 里。重复这个过程直到两个指针相遇（数据都分区好了），最后把原本挖出去的基准值再填回来（这个时候坑位正好在中间）。这就成功完成了一次分区过程，递归即可。</p>\n<figure class=\"highlight c\"><figcaption data-lang=\"c\"><span>快速排序 挖坑法</span></figcaption><table><tr><td data-num=\"1\"></td><td><pre><span class=\"token keyword\">void</span> <span class=\"token function\">QuickSortDigHole</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">int</span><span class=\"token operator\">*</span> arr<span class=\"token punctuation\">,</span> <span class=\"token keyword\">int</span> left<span class=\"token punctuation\">,</span> <span class=\"token keyword\">int</span> right<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"2\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"3\"></td><td><pre>\t<span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>left <span class=\"token operator\">>=</span> right<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"4\"></td><td><pre>\t<span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"5\"></td><td><pre>\t\t<span class=\"token keyword\">return</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"6\"></td><td><pre>\t<span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"7\"></td><td><pre>\t<span class=\"token keyword\">int</span> key <span class=\"token operator\">=</span> left<span class=\"token punctuation\">,</span> begin <span class=\"token operator\">=</span> left<span class=\"token punctuation\">,</span> end <span class=\"token operator\">=</span> right<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"8\"></td><td><pre>\t<span class=\"token keyword\">int</span> tmp <span class=\"token operator\">=</span> arr<span class=\"token punctuation\">[</span>key<span class=\"token punctuation\">]</span><span class=\"token punctuation\">;</span>\t<span class=\"token comment\">// 挖坑</span></pre></td></tr><tr><td data-num=\"9\"></td><td><pre>\t<span class=\"token keyword\">while</span> <span class=\"token punctuation\">(</span>left <span class=\"token operator\">&lt;</span> right<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"10\"></td><td><pre>\t<span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"11\"></td><td><pre>\t\t<span class=\"token keyword\">while</span> <span class=\"token punctuation\">(</span>left <span class=\"token operator\">&lt;</span> right <span class=\"token operator\">&amp;&amp;</span> arr<span class=\"token punctuation\">[</span>right<span class=\"token punctuation\">]</span> <span class=\"token operator\">>=</span> tmp<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"12\"></td><td><pre>\t\t<span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"13\"></td><td><pre>\t\t\t<span class=\"token operator\">--</span>right<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"14\"></td><td><pre>\t\t<span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"15\"></td><td><pre>\t\tarr<span class=\"token punctuation\">[</span>left<span class=\"token punctuation\">]</span> <span class=\"token operator\">=</span> arr<span class=\"token punctuation\">[</span>right<span class=\"token punctuation\">]</span><span class=\"token punctuation\">;</span>\t<span class=\"token comment\">// 此时坑位从左边变为右边</span></pre></td></tr><tr><td data-num=\"16\"></td><td><pre>\t\t<span class=\"token keyword\">while</span> <span class=\"token punctuation\">(</span>left <span class=\"token operator\">&lt;</span> right <span class=\"token operator\">&amp;&amp;</span> arr<span class=\"token punctuation\">[</span>left<span class=\"token punctuation\">]</span> <span class=\"token operator\">&lt;=</span> tmp<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"17\"></td><td><pre>\t\t<span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"18\"></td><td><pre>\t\t\t<span class=\"token operator\">++</span>left<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"19\"></td><td><pre>\t\t<span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"20\"></td><td><pre>\t\tarr<span class=\"token punctuation\">[</span>right<span class=\"token punctuation\">]</span> <span class=\"token operator\">=</span> arr<span class=\"token punctuation\">[</span>left<span class=\"token punctuation\">]</span><span class=\"token punctuation\">;</span>\t<span class=\"token comment\">// 此时坑位从右边变为左边</span></pre></td></tr><tr><td data-num=\"21\"></td><td><pre>\t<span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"22\"></td><td><pre>\tarr<span class=\"token punctuation\">[</span>left<span class=\"token punctuation\">]</span> <span class=\"token operator\">=</span> tmp<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"23\"></td><td><pre>\t<span class=\"token function\">QuickSort</span><span class=\"token punctuation\">(</span>arr<span class=\"token punctuation\">,</span> begin<span class=\"token punctuation\">,</span> left <span class=\"token operator\">-</span> <span class=\"token number\">1</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"24\"></td><td><pre>\t<span class=\"token function\">QuickSort</span><span class=\"token punctuation\">(</span>arr<span class=\"token punctuation\">,</span> left <span class=\"token operator\">+</span> <span class=\"token number\">1</span><span class=\"token punctuation\">,</span> end<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"25\"></td><td><pre><span class=\"token punctuation\">&#125;</span></pre></td></tr></table></figure><h6 id=\"最好书写的快速排序-前后指针法\"><a class=\"anchor\" href=\"#最好书写的快速排序-前后指针法\">#</a> 最好书写的快速排序 - 前后指针法</h6>\n<p><img data-src=\"prevcur.gif\" alt=\"前后指针法\" /></p>\n<p>前后指针法的代码更简洁，也不难理解。</p>\n<p>就是一开始把 prev 标记放在 left（还是假设 key=left），cur 标记放在 left+1，然后前指针 cur 一直往前冲，遇到比基准值小的数就和后指针 prev 标记的值对调，再让后指针往前一步。重复这个过程让小于基准的值全部堆到数组的前面（准确说是 prev 的前面），最后把 key 标记的值和 prev 标记的对调就完成了一次分区。 递归即可。</p>\n<figure class=\"highlight c\"><figcaption data-lang=\"c\"><span>快速排序 前后指针法</span></figcaption><table><tr><td data-num=\"1\"></td><td><pre><span class=\"token keyword\">void</span> <span class=\"token function\">QuickSortPrevCur</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">int</span><span class=\"token operator\">*</span> arr<span class=\"token punctuation\">,</span> <span class=\"token keyword\">int</span> left<span class=\"token punctuation\">,</span> <span class=\"token keyword\">int</span> right<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"2\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"3\"></td><td><pre>\t<span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>left <span class=\"token operator\">>=</span> right<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"4\"></td><td><pre>\t<span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"5\"></td><td><pre>\t\t<span class=\"token keyword\">return</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"6\"></td><td><pre>\t<span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"7\"></td><td><pre>\t<span class=\"token keyword\">int</span> key <span class=\"token operator\">=</span> left<span class=\"token punctuation\">,</span> begin <span class=\"token operator\">=</span> left<span class=\"token punctuation\">,</span> end <span class=\"token operator\">=</span> right<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"8\"></td><td><pre>\t<span class=\"token keyword\">int</span> prev <span class=\"token operator\">=</span> left<span class=\"token punctuation\">,</span> cur <span class=\"token operator\">=</span> left <span class=\"token operator\">+</span> <span class=\"token number\">1</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"9\"></td><td><pre>\t<span class=\"token keyword\">while</span> <span class=\"token punctuation\">(</span>cur <span class=\"token operator\">&lt;=</span> right<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"10\"></td><td><pre>\t<span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"11\"></td><td><pre>\t\t<span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>arr<span class=\"token punctuation\">[</span>cur<span class=\"token punctuation\">]</span> <span class=\"token operator\">&lt;</span> arr<span class=\"token punctuation\">[</span>key<span class=\"token punctuation\">]</span> <span class=\"token operator\">&amp;&amp;</span> <span class=\"token operator\">++</span>prev <span class=\"token operator\">!=</span> cur<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"12\"></td><td><pre>\t\t<span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"13\"></td><td><pre>\t\t\t<span class=\"token function\">Swap</span><span class=\"token punctuation\">(</span><span class=\"token operator\">&amp;</span>arr<span class=\"token punctuation\">[</span>prev<span class=\"token punctuation\">]</span><span class=\"token punctuation\">,</span> <span class=\"token operator\">&amp;</span>arr<span class=\"token punctuation\">[</span>cur<span class=\"token punctuation\">]</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"14\"></td><td><pre>\t\t<span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"15\"></td><td><pre>\t\t<span class=\"token operator\">++</span>cur<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"16\"></td><td><pre>\t<span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"17\"></td><td><pre>\t<span class=\"token function\">Swap</span><span class=\"token punctuation\">(</span><span class=\"token operator\">&amp;</span>arr<span class=\"token punctuation\">[</span>prev<span class=\"token punctuation\">]</span><span class=\"token punctuation\">,</span> <span class=\"token operator\">&amp;</span>arr<span class=\"token punctuation\">[</span>key<span class=\"token punctuation\">]</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"18\"></td><td><pre>\tkey <span class=\"token operator\">=</span> prev<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"19\"></td><td><pre>\t<span class=\"token comment\">//[begin, key - 1] [key] [key + 1, end]</span></pre></td></tr><tr><td data-num=\"20\"></td><td><pre>\t<span class=\"token function\">QuickSort</span><span class=\"token punctuation\">(</span>arr<span class=\"token punctuation\">,</span> begin<span class=\"token punctuation\">,</span> key <span class=\"token operator\">-</span> <span class=\"token number\">1</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"21\"></td><td><pre>\t<span class=\"token function\">QuickSort</span><span class=\"token punctuation\">(</span>arr<span class=\"token punctuation\">,</span> key <span class=\"token operator\">+</span> <span class=\"token number\">1</span><span class=\"token punctuation\">,</span> end<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"22\"></td><td><pre><span class=\"token punctuation\">&#125;</span></pre></td></tr></table></figure><h6 id=\"不使用递归的方法-栈模拟递归\"><a class=\"anchor\" href=\"#不使用递归的方法-栈模拟递归\">#</a> 不使用递归的方法 - 栈模拟递归</h6>\n<p>这个方法没怎么好说的，就是用栈模拟递归，里面每一次分区依旧可以选择上面任意一种方法。</p>\n<figure class=\"highlight c\"><figcaption data-lang=\"c\"><span>快速排序 非递归</span></figcaption><table><tr><td data-num=\"1\"></td><td><pre><span class=\"token keyword\">void</span> <span class=\"token function\">InitStack</span><span class=\"token punctuation\">(</span>pStack pst<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"2\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"3\"></td><td><pre>\t<span class=\"token function\">assert</span><span class=\"token punctuation\">(</span>pst<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"4\"></td><td><pre>\tpst<span class=\"token operator\">-></span>_data <span class=\"token operator\">=</span> <span class=\"token constant\">NULL</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"5\"></td><td><pre>\tpst<span class=\"token operator\">-></span>_top <span class=\"token operator\">=</span> <span class=\"token number\">0</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"6\"></td><td><pre>\tpst<span class=\"token operator\">-></span>_capacity <span class=\"token operator\">=</span> <span class=\"token number\">0</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"7\"></td><td><pre><span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"8\"></td><td><pre></pre></td></tr><tr><td data-num=\"9\"></td><td><pre><span class=\"token keyword\">void</span> <span class=\"token function\">StackPush</span><span class=\"token punctuation\">(</span>pStack pst<span class=\"token punctuation\">,</span> STDataType x<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"10\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"11\"></td><td><pre>\t<span class=\"token function\">assert</span><span class=\"token punctuation\">(</span>pst<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"12\"></td><td><pre>\t<span class=\"token function\">StackCheck</span><span class=\"token punctuation\">(</span>pst<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span> </pre></td></tr><tr><td data-num=\"13\"></td><td><pre>\t<span class=\"token function\">memcpy</span><span class=\"token punctuation\">(</span><span class=\"token operator\">&amp;</span><span class=\"token punctuation\">(</span>pst<span class=\"token operator\">-></span>_data<span class=\"token punctuation\">[</span>pst<span class=\"token operator\">-></span>_top<span class=\"token punctuation\">]</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">,</span> <span class=\"token operator\">&amp;</span>x<span class=\"token punctuation\">,</span> <span class=\"token keyword\">sizeof</span><span class=\"token punctuation\">(</span>STDataType<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"14\"></td><td><pre>\tpst<span class=\"token operator\">-></span>_top<span class=\"token operator\">++</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"15\"></td><td><pre><span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"16\"></td><td><pre></pre></td></tr><tr><td data-num=\"17\"></td><td><pre><span class=\"token keyword\">void</span> <span class=\"token function\">StackPop</span><span class=\"token punctuation\">(</span>pStack pst<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"18\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"19\"></td><td><pre>\t<span class=\"token function\">assert</span><span class=\"token punctuation\">(</span>pst<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"20\"></td><td><pre>\t<span class=\"token function\">assert</span><span class=\"token punctuation\">(</span><span class=\"token operator\">!</span><span class=\"token function\">StackEmpty</span><span class=\"token punctuation\">(</span>pst<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"21\"></td><td><pre>\tpst<span class=\"token operator\">-></span>_top<span class=\"token operator\">--</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"22\"></td><td><pre><span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"23\"></td><td><pre></pre></td></tr><tr><td data-num=\"24\"></td><td><pre>STDataType <span class=\"token function\">StackTop</span><span class=\"token punctuation\">(</span>pStack pst<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"25\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"26\"></td><td><pre>\t<span class=\"token function\">assert</span><span class=\"token punctuation\">(</span>pst<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"27\"></td><td><pre>\t<span class=\"token keyword\">return</span> pst<span class=\"token operator\">-></span>_data<span class=\"token punctuation\">[</span>pst<span class=\"token operator\">-></span>_top <span class=\"token operator\">-</span> <span class=\"token number\">1</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"28\"></td><td><pre><span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"29\"></td><td><pre></pre></td></tr><tr><td data-num=\"30\"></td><td><pre><span class=\"token keyword\">void</span> <span class=\"token function\">StackDestory</span><span class=\"token punctuation\">(</span>pStack pst<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"31\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"32\"></td><td><pre>\t<span class=\"token function\">assert</span><span class=\"token punctuation\">(</span>pst<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"33\"></td><td><pre>\t<span class=\"token function\">free</span><span class=\"token punctuation\">(</span>pst<span class=\"token operator\">-></span>_data<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"34\"></td><td><pre>\tpst<span class=\"token operator\">-></span>_capacity <span class=\"token operator\">=</span> <span class=\"token number\">0</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"35\"></td><td><pre>\tpst<span class=\"token operator\">-></span>_top <span class=\"token operator\">=</span> <span class=\"token number\">0</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"36\"></td><td><pre>\tpst<span class=\"token operator\">-></span>_data <span class=\"token operator\">=</span> <span class=\"token constant\">NULL</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"37\"></td><td><pre><span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"38\"></td><td><pre></pre></td></tr><tr><td data-num=\"39\"></td><td><pre><span class=\"token keyword\">void</span> <span class=\"token function\">QuickSortNonR</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">int</span><span class=\"token operator\">*</span> arr<span class=\"token punctuation\">,</span> <span class=\"token keyword\">int</span> left<span class=\"token punctuation\">,</span> <span class=\"token keyword\">int</span> right<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"40\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"41\"></td><td><pre>\t<span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>left <span class=\"token operator\">>=</span> right<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"42\"></td><td><pre>\t<span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"43\"></td><td><pre>\t\t<span class=\"token keyword\">return</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"44\"></td><td><pre>\t<span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"45\"></td><td><pre>\tStack st<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"46\"></td><td><pre>\t<span class=\"token function\">InitStack</span><span class=\"token punctuation\">(</span><span class=\"token operator\">&amp;</span>st<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"47\"></td><td><pre>\t<span class=\"token function\">StackPush</span><span class=\"token punctuation\">(</span><span class=\"token operator\">&amp;</span>st<span class=\"token punctuation\">,</span> left<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"48\"></td><td><pre>\t<span class=\"token function\">StackPush</span><span class=\"token punctuation\">(</span><span class=\"token operator\">&amp;</span>st<span class=\"token punctuation\">,</span> right<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"49\"></td><td><pre>\t<span class=\"token keyword\">while</span> <span class=\"token punctuation\">(</span><span class=\"token operator\">!</span><span class=\"token function\">StackEmpty</span><span class=\"token punctuation\">(</span><span class=\"token operator\">&amp;</span>st<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"50\"></td><td><pre>\t<span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"51\"></td><td><pre>\t\t<span class=\"token keyword\">int</span> end <span class=\"token operator\">=</span> <span class=\"token function\">StackTop</span><span class=\"token punctuation\">(</span><span class=\"token operator\">&amp;</span>st<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"52\"></td><td><pre>\t\t<span class=\"token function\">StackPop</span><span class=\"token punctuation\">(</span><span class=\"token operator\">&amp;</span>st<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"53\"></td><td><pre>\t\t<span class=\"token keyword\">int</span> begin <span class=\"token operator\">=</span> <span class=\"token function\">StackTop</span><span class=\"token punctuation\">(</span><span class=\"token operator\">&amp;</span>st<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"54\"></td><td><pre>\t\t<span class=\"token function\">StackPop</span><span class=\"token punctuation\">(</span><span class=\"token operator\">&amp;</span>st<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"55\"></td><td><pre>\t\t<span class=\"token keyword\">int</span> key <span class=\"token operator\">=</span> begin<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"56\"></td><td><pre>\t\t<span class=\"token keyword\">int</span> prev <span class=\"token operator\">=</span> begin<span class=\"token punctuation\">,</span> cur <span class=\"token operator\">=</span> begin <span class=\"token operator\">+</span> <span class=\"token number\">1</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"57\"></td><td><pre>\t\t<span class=\"token keyword\">while</span> <span class=\"token punctuation\">(</span>cur <span class=\"token operator\">&lt;=</span> end<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"58\"></td><td><pre>\t\t<span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"59\"></td><td><pre>\t\t\t<span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>arr<span class=\"token punctuation\">[</span>cur<span class=\"token punctuation\">]</span> <span class=\"token operator\">&lt;</span> arr<span class=\"token punctuation\">[</span>key<span class=\"token punctuation\">]</span> <span class=\"token operator\">&amp;&amp;</span> <span class=\"token operator\">++</span>prev <span class=\"token operator\">!=</span> cur<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"60\"></td><td><pre>\t\t\t<span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"61\"></td><td><pre>\t\t\t\t<span class=\"token function\">Swap</span><span class=\"token punctuation\">(</span><span class=\"token operator\">&amp;</span>arr<span class=\"token punctuation\">[</span>prev<span class=\"token punctuation\">]</span><span class=\"token punctuation\">,</span> <span class=\"token operator\">&amp;</span>arr<span class=\"token punctuation\">[</span>cur<span class=\"token punctuation\">]</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"62\"></td><td><pre>\t\t\t<span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"63\"></td><td><pre>\t\t\t<span class=\"token operator\">++</span>cur<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"64\"></td><td><pre>\t\t<span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"65\"></td><td><pre>\t\t<span class=\"token function\">Swap</span><span class=\"token punctuation\">(</span><span class=\"token operator\">&amp;</span>arr<span class=\"token punctuation\">[</span>prev<span class=\"token punctuation\">]</span><span class=\"token punctuation\">,</span> <span class=\"token operator\">&amp;</span>arr<span class=\"token punctuation\">[</span>key<span class=\"token punctuation\">]</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"66\"></td><td><pre>\t\tkey <span class=\"token operator\">=</span> prev<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"67\"></td><td><pre>\t\t<span class=\"token comment\">//[begin, key - 1] [key] [key + 1, end]</span></pre></td></tr><tr><td data-num=\"68\"></td><td><pre>\t\t<span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>begin <span class=\"token operator\">&lt;</span> key <span class=\"token operator\">-</span> <span class=\"token number\">1</span><span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"69\"></td><td><pre>\t\t<span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"70\"></td><td><pre>\t\t\t<span class=\"token function\">StackPush</span><span class=\"token punctuation\">(</span><span class=\"token operator\">&amp;</span>st<span class=\"token punctuation\">,</span> begin<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"71\"></td><td><pre>\t\t\t<span class=\"token function\">StackPush</span><span class=\"token punctuation\">(</span><span class=\"token operator\">&amp;</span>st<span class=\"token punctuation\">,</span> key <span class=\"token operator\">-</span> <span class=\"token number\">1</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"72\"></td><td><pre>\t\t<span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"73\"></td><td><pre>\t\t<span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>key <span class=\"token operator\">+</span> <span class=\"token number\">1</span> <span class=\"token operator\">&lt;</span> end<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"74\"></td><td><pre>\t\t<span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"75\"></td><td><pre>\t\t\t<span class=\"token function\">StackPush</span><span class=\"token punctuation\">(</span><span class=\"token operator\">&amp;</span>st<span class=\"token punctuation\">,</span> key <span class=\"token operator\">+</span> <span class=\"token number\">1</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"76\"></td><td><pre>\t\t\t<span class=\"token function\">StackPush</span><span class=\"token punctuation\">(</span><span class=\"token operator\">&amp;</span>st<span class=\"token punctuation\">,</span> end<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"77\"></td><td><pre>\t\t<span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"78\"></td><td><pre>\t<span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"79\"></td><td><pre>\t<span class=\"token function\">StackDestory</span><span class=\"token punctuation\">(</span><span class=\"token operator\">&amp;</span>st<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"80\"></td><td><pre><span class=\"token punctuation\">&#125;</span></pre></td></tr></table></figure><h6 id=\"区别\"><a class=\"anchor\" href=\"#区别\">#</a> 区别</h6>\n<p>除了非递归的方法，这几个实现的时间复杂度并没有太多区别，使用非递归的方法会慢一点点。下面是对一千万个随机数据的排序测试（单位毫秒）：</p>\n<p><img data-src=\"test1.png\" alt=\"测试\" /></p>\n<h5 id=\"优化\"><a class=\"anchor\" href=\"#优化\">#</a> 优化</h5>\n<h6 id=\"随机选key优化快速排序\"><a class=\"anchor\" href=\"#随机选key优化快速排序\">#</a> 随机选 Key 优化快速排序</h6>\n<p>这个方法是在<mark>序列中随机选一个值</mark>和首元素调换再作为基准值，大大减小了遇到最坏情况（每次选 key 是有序的）的可能。</p>\n<figure class=\"highlight c\"><figcaption data-lang=\"c\"><span>快速排序 随机选key</span></figcaption><table><tr><td data-num=\"1\"></td><td><pre><span class=\"token keyword\">void</span> <span class=\"token function\">QuickSortRandomKey</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">int</span><span class=\"token operator\">*</span> arr<span class=\"token punctuation\">,</span> <span class=\"token keyword\">int</span> left<span class=\"token punctuation\">,</span> <span class=\"token keyword\">int</span> right<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"2\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"3\"></td><td><pre>\t<span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>left <span class=\"token operator\">>=</span> right<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"4\"></td><td><pre>\t<span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"5\"></td><td><pre>\t\t<span class=\"token keyword\">return</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"6\"></td><td><pre>\t<span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"7\"></td><td><pre>\t<span class=\"token keyword\">int</span> key <span class=\"token operator\">=</span> left<span class=\"token punctuation\">,</span> begin <span class=\"token operator\">=</span> left<span class=\"token punctuation\">,</span> end <span class=\"token operator\">=</span> right<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"8\"></td><td><pre></pre></td></tr><tr><td data-num=\"9\"></td><td><pre>\t<span class=\"token comment\">// 生成随机数并将该位置与首位调换</span></pre></td></tr><tr><td data-num=\"10\"></td><td><pre>\t<span class=\"token keyword\">int</span> random <span class=\"token operator\">=</span> <span class=\"token function\">rand</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">%</span> <span class=\"token punctuation\">(</span>right <span class=\"token operator\">-</span> left <span class=\"token operator\">+</span> <span class=\"token number\">1</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">+</span> left<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"11\"></td><td><pre>\t<span class=\"token function\">Swap</span><span class=\"token punctuation\">(</span><span class=\"token operator\">&amp;</span>arr<span class=\"token punctuation\">[</span>random<span class=\"token punctuation\">]</span><span class=\"token punctuation\">,</span> <span class=\"token operator\">&amp;</span>arr<span class=\"token punctuation\">[</span>left<span class=\"token punctuation\">]</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"12\"></td><td><pre></pre></td></tr><tr><td data-num=\"13\"></td><td><pre>\t<span class=\"token keyword\">while</span> <span class=\"token punctuation\">(</span>left <span class=\"token operator\">&lt;</span> right<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"14\"></td><td><pre>\t<span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"15\"></td><td><pre>\t\t<span class=\"token keyword\">while</span> <span class=\"token punctuation\">(</span>left <span class=\"token operator\">&lt;</span> right <span class=\"token operator\">&amp;&amp;</span> arr<span class=\"token punctuation\">[</span>right<span class=\"token punctuation\">]</span> <span class=\"token operator\">>=</span> arr<span class=\"token punctuation\">[</span>key<span class=\"token punctuation\">]</span><span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"16\"></td><td><pre>\t\t<span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"17\"></td><td><pre>\t\t\t<span class=\"token operator\">--</span>right<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"18\"></td><td><pre>\t\t<span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"19\"></td><td><pre>\t\t<span class=\"token keyword\">while</span> <span class=\"token punctuation\">(</span>left <span class=\"token operator\">&lt;</span> right <span class=\"token operator\">&amp;&amp;</span> arr<span class=\"token punctuation\">[</span>left<span class=\"token punctuation\">]</span> <span class=\"token operator\">&lt;=</span> arr<span class=\"token punctuation\">[</span>key<span class=\"token punctuation\">]</span><span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"20\"></td><td><pre>\t\t<span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"21\"></td><td><pre>\t\t\t<span class=\"token operator\">++</span>left<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"22\"></td><td><pre>\t\t<span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"23\"></td><td><pre>\t\t<span class=\"token function\">Swap</span><span class=\"token punctuation\">(</span><span class=\"token operator\">&amp;</span>arr<span class=\"token punctuation\">[</span>left<span class=\"token punctuation\">]</span><span class=\"token punctuation\">,</span> <span class=\"token operator\">&amp;</span>arr<span class=\"token punctuation\">[</span>right<span class=\"token punctuation\">]</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"24\"></td><td><pre>\t<span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"25\"></td><td><pre>\t<span class=\"token function\">Swap</span><span class=\"token punctuation\">(</span><span class=\"token operator\">&amp;</span>arr<span class=\"token punctuation\">[</span>left<span class=\"token punctuation\">]</span><span class=\"token punctuation\">,</span> <span class=\"token operator\">&amp;</span>arr<span class=\"token punctuation\">[</span>key<span class=\"token punctuation\">]</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"26\"></td><td><pre>\t<span class=\"token function\">QuickSort</span><span class=\"token punctuation\">(</span>arr<span class=\"token punctuation\">,</span> begin<span class=\"token punctuation\">,</span> left <span class=\"token operator\">-</span> <span class=\"token number\">1</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"27\"></td><td><pre>\t<span class=\"token function\">QuickSort</span><span class=\"token punctuation\">(</span>arr<span class=\"token punctuation\">,</span> left <span class=\"token operator\">+</span> <span class=\"token number\">1</span><span class=\"token punctuation\">,</span> end<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"28\"></td><td><pre><span class=\"token punctuation\">&#125;</span></pre></td></tr></table></figure><h6 id=\"三数取中优化快速排序\"><a class=\"anchor\" href=\"#三数取中优化快速排序\">#</a> 三数取中优化快速排序</h6>\n<p>这个方法是<mark>取序列中 left、right、(left+right)/2 所对应的值的中位数</mark>与首元素调换作为基准值，这几乎完全避免了最坏情况的可能。</p>\n<figure class=\"highlight c\"><figcaption data-lang=\"c\"><span>快速排序 三数取中法</span></figcaption><table><tr><td data-num=\"1\"></td><td><pre><span class=\"token keyword\">int</span> <span class=\"token function\">GetMid</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">int</span><span class=\"token operator\">*</span> arr<span class=\"token punctuation\">,</span> <span class=\"token keyword\">int</span> left<span class=\"token punctuation\">,</span> <span class=\"token keyword\">int</span> right<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"2\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"3\"></td><td><pre>\t<span class=\"token keyword\">int</span> center <span class=\"token operator\">=</span> <span class=\"token punctuation\">(</span>left <span class=\"token operator\">+</span> right<span class=\"token punctuation\">)</span> <span class=\"token operator\">/</span> <span class=\"token number\">2</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"4\"></td><td><pre>\t<span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>arr<span class=\"token punctuation\">[</span>left<span class=\"token punctuation\">]</span> <span class=\"token operator\">></span> arr<span class=\"token punctuation\">[</span>center<span class=\"token punctuation\">]</span><span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"5\"></td><td><pre>\t<span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"6\"></td><td><pre>\t\t<span class=\"token function\">Swap</span><span class=\"token punctuation\">(</span><span class=\"token operator\">&amp;</span>arr<span class=\"token punctuation\">[</span>left<span class=\"token punctuation\">]</span><span class=\"token punctuation\">,</span> <span class=\"token operator\">&amp;</span>arr<span class=\"token punctuation\">[</span>center<span class=\"token punctuation\">]</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"7\"></td><td><pre>\t<span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"8\"></td><td><pre>\t<span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>arr<span class=\"token punctuation\">[</span>left<span class=\"token punctuation\">]</span> <span class=\"token operator\">></span> arr<span class=\"token punctuation\">[</span>right<span class=\"token punctuation\">]</span><span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"9\"></td><td><pre>\t<span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"10\"></td><td><pre>\t\t<span class=\"token function\">Swap</span><span class=\"token punctuation\">(</span><span class=\"token operator\">&amp;</span>arr<span class=\"token punctuation\">[</span>left<span class=\"token punctuation\">]</span><span class=\"token punctuation\">,</span> <span class=\"token operator\">&amp;</span>arr<span class=\"token punctuation\">[</span>right<span class=\"token punctuation\">]</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"11\"></td><td><pre>\t<span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"12\"></td><td><pre>\t<span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>arr<span class=\"token punctuation\">[</span>left<span class=\"token punctuation\">]</span> <span class=\"token operator\">></span> arr<span class=\"token punctuation\">[</span>center<span class=\"token punctuation\">]</span><span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"13\"></td><td><pre>\t<span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"14\"></td><td><pre>\t\t<span class=\"token function\">Swap</span><span class=\"token punctuation\">(</span><span class=\"token operator\">&amp;</span>arr<span class=\"token punctuation\">[</span>center<span class=\"token punctuation\">]</span><span class=\"token punctuation\">,</span> <span class=\"token operator\">&amp;</span>arr<span class=\"token punctuation\">[</span>right<span class=\"token punctuation\">]</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"15\"></td><td><pre>\t<span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"16\"></td><td><pre>\t<span class=\"token keyword\">return</span> arr<span class=\"token punctuation\">[</span>center<span class=\"token punctuation\">]</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"17\"></td><td><pre><span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"18\"></td><td><pre></pre></td></tr><tr><td data-num=\"19\"></td><td><pre><span class=\"token keyword\">void</span> <span class=\"token function\">QuickSortMidKey</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">int</span><span class=\"token operator\">*</span> arr<span class=\"token punctuation\">,</span> <span class=\"token keyword\">int</span> left<span class=\"token punctuation\">,</span> <span class=\"token keyword\">int</span> right<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"20\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"21\"></td><td><pre>\t<span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>left <span class=\"token operator\">>=</span> right<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"22\"></td><td><pre>\t<span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"23\"></td><td><pre>\t\t<span class=\"token keyword\">return</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"24\"></td><td><pre>\t<span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"25\"></td><td><pre>\t<span class=\"token keyword\">int</span> key <span class=\"token operator\">=</span> left<span class=\"token punctuation\">,</span> begin <span class=\"token operator\">=</span> left<span class=\"token punctuation\">,</span> end <span class=\"token operator\">=</span> right<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"26\"></td><td><pre></pre></td></tr><tr><td data-num=\"27\"></td><td><pre>\t<span class=\"token comment\">// 三数取中</span></pre></td></tr><tr><td data-num=\"28\"></td><td><pre>\t<span class=\"token keyword\">int</span> mid <span class=\"token operator\">=</span> <span class=\"token function\">GetMid</span><span class=\"token punctuation\">(</span>arr<span class=\"token punctuation\">,</span> left<span class=\"token punctuation\">,</span> right<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"29\"></td><td><pre>\t<span class=\"token function\">Swap</span><span class=\"token punctuation\">(</span><span class=\"token operator\">&amp;</span>arr<span class=\"token punctuation\">[</span>mid<span class=\"token punctuation\">]</span><span class=\"token punctuation\">,</span> <span class=\"token operator\">&amp;</span>arr<span class=\"token punctuation\">[</span>left<span class=\"token punctuation\">]</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"30\"></td><td><pre></pre></td></tr><tr><td data-num=\"31\"></td><td><pre>\t<span class=\"token keyword\">while</span> <span class=\"token punctuation\">(</span>left <span class=\"token operator\">&lt;</span> right<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"32\"></td><td><pre>\t<span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"33\"></td><td><pre>\t\t<span class=\"token keyword\">while</span> <span class=\"token punctuation\">(</span>left <span class=\"token operator\">&lt;</span> right <span class=\"token operator\">&amp;&amp;</span> arr<span class=\"token punctuation\">[</span>right<span class=\"token punctuation\">]</span> <span class=\"token operator\">>=</span> arr<span class=\"token punctuation\">[</span>key<span class=\"token punctuation\">]</span><span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"34\"></td><td><pre>\t\t<span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"35\"></td><td><pre>\t\t\t<span class=\"token operator\">--</span>right<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"36\"></td><td><pre>\t\t<span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"37\"></td><td><pre>\t\t<span class=\"token keyword\">while</span> <span class=\"token punctuation\">(</span>left <span class=\"token operator\">&lt;</span> right <span class=\"token operator\">&amp;&amp;</span> arr<span class=\"token punctuation\">[</span>left<span class=\"token punctuation\">]</span> <span class=\"token operator\">&lt;=</span> arr<span class=\"token punctuation\">[</span>key<span class=\"token punctuation\">]</span><span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"38\"></td><td><pre>\t\t<span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"39\"></td><td><pre>\t\t\t<span class=\"token operator\">++</span>left<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"40\"></td><td><pre>\t\t<span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"41\"></td><td><pre>\t\t<span class=\"token function\">Swap</span><span class=\"token punctuation\">(</span><span class=\"token operator\">&amp;</span>arr<span class=\"token punctuation\">[</span>left<span class=\"token punctuation\">]</span><span class=\"token punctuation\">,</span> <span class=\"token operator\">&amp;</span>arr<span class=\"token punctuation\">[</span>right<span class=\"token punctuation\">]</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"42\"></td><td><pre>\t<span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"43\"></td><td><pre>\t<span class=\"token function\">Swap</span><span class=\"token punctuation\">(</span><span class=\"token operator\">&amp;</span>arr<span class=\"token punctuation\">[</span>left<span class=\"token punctuation\">]</span><span class=\"token punctuation\">,</span> <span class=\"token operator\">&amp;</span>arr<span class=\"token punctuation\">[</span>key<span class=\"token punctuation\">]</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"44\"></td><td><pre>\t<span class=\"token function\">QuickSort</span><span class=\"token punctuation\">(</span>arr<span class=\"token punctuation\">,</span> begin<span class=\"token punctuation\">,</span> left <span class=\"token operator\">-</span> <span class=\"token number\">1</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"45\"></td><td><pre>\t<span class=\"token function\">QuickSort</span><span class=\"token punctuation\">(</span>arr<span class=\"token punctuation\">,</span> left <span class=\"token operator\">+</span> <span class=\"token number\">1</span><span class=\"token punctuation\">,</span> end<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"46\"></td><td><pre><span class=\"token punctuation\">&#125;</span></pre></td></tr></table></figure><h6 id=\"小区间优化快速排序\"><a class=\"anchor\" href=\"#小区间优化快速排序\">#</a> 小区间优化快速排序</h6>\n<p>当递归已经进行到序列变的很短的时候，依旧选择继续递归快速排序的效率其实较低，反而不如将已经较短的序列拿去进行插入排序。所以在递归时加上一个选择语句进行优化：</p>\n<figure class=\"highlight c\"><figcaption data-lang=\"c\"><span>快速排序 小区间优化</span></figcaption><table><tr><td data-num=\"1\"></td><td><pre><span class=\"token keyword\">void</span> <span class=\"token function\">QuickSortOptimized</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">int</span><span class=\"token operator\">*</span> arr<span class=\"token punctuation\">,</span> <span class=\"token keyword\">int</span> left<span class=\"token punctuation\">,</span> <span class=\"token keyword\">int</span> right<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"2\"></td><td><pre><span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"3\"></td><td><pre>\t<span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>left <span class=\"token operator\">>=</span> right<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"4\"></td><td><pre>\t<span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"5\"></td><td><pre>\t\t<span class=\"token keyword\">return</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"6\"></td><td><pre>\t<span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"7\"></td><td><pre>\t<span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>right <span class=\"token operator\">-</span> left <span class=\"token operator\">&lt;</span> <span class=\"token number\">10</span><span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"8\"></td><td><pre>\t<span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"9\"></td><td><pre>\t\t<span class=\"token function\">InsertSort</span><span class=\"token punctuation\">(</span>arr <span class=\"token operator\">+</span> left<span class=\"token punctuation\">,</span> right <span class=\"token operator\">-</span> left <span class=\"token operator\">+</span> <span class=\"token number\">1</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"10\"></td><td><pre>\t<span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"11\"></td><td><pre>\t<span class=\"token keyword\">else</span></pre></td></tr><tr><td data-num=\"12\"></td><td><pre>\t<span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"13\"></td><td><pre>\t\t<span class=\"token keyword\">int</span> key <span class=\"token operator\">=</span> left<span class=\"token punctuation\">,</span> begin <span class=\"token operator\">=</span> left<span class=\"token punctuation\">,</span> end <span class=\"token operator\">=</span> right<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"14\"></td><td><pre></pre></td></tr><tr><td data-num=\"15\"></td><td><pre>\t\t<span class=\"token keyword\">while</span> <span class=\"token punctuation\">(</span>left <span class=\"token operator\">&lt;</span> right<span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"16\"></td><td><pre>\t\t<span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"17\"></td><td><pre>\t\t\t<span class=\"token keyword\">while</span> <span class=\"token punctuation\">(</span>left <span class=\"token operator\">&lt;</span> right <span class=\"token operator\">&amp;&amp;</span> arr<span class=\"token punctuation\">[</span>right<span class=\"token punctuation\">]</span> <span class=\"token operator\">>=</span> arr<span class=\"token punctuation\">[</span>key<span class=\"token punctuation\">]</span><span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"18\"></td><td><pre>\t\t\t<span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"19\"></td><td><pre>\t\t\t\t<span class=\"token operator\">--</span>right<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"20\"></td><td><pre>\t\t\t<span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"21\"></td><td><pre>\t\t\t<span class=\"token keyword\">while</span> <span class=\"token punctuation\">(</span>left <span class=\"token operator\">&lt;</span> right <span class=\"token operator\">&amp;&amp;</span> arr<span class=\"token punctuation\">[</span>left<span class=\"token punctuation\">]</span> <span class=\"token operator\">&lt;=</span> arr<span class=\"token punctuation\">[</span>key<span class=\"token punctuation\">]</span><span class=\"token punctuation\">)</span></pre></td></tr><tr><td data-num=\"22\"></td><td><pre>\t\t\t<span class=\"token punctuation\">&#123;</span></pre></td></tr><tr><td data-num=\"23\"></td><td><pre>\t\t\t\t<span class=\"token operator\">++</span>left<span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"24\"></td><td><pre>\t\t\t<span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"25\"></td><td><pre>\t\t\t<span class=\"token function\">Swap</span><span class=\"token punctuation\">(</span><span class=\"token operator\">&amp;</span>arr<span class=\"token punctuation\">[</span>left<span class=\"token punctuation\">]</span><span class=\"token punctuation\">,</span> <span class=\"token operator\">&amp;</span>arr<span class=\"token punctuation\">[</span>right<span class=\"token punctuation\">]</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"26\"></td><td><pre>\t\t<span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"27\"></td><td><pre>\t\t<span class=\"token function\">Swap</span><span class=\"token punctuation\">(</span><span class=\"token operator\">&amp;</span>arr<span class=\"token punctuation\">[</span>left<span class=\"token punctuation\">]</span><span class=\"token punctuation\">,</span> <span class=\"token operator\">&amp;</span>arr<span class=\"token punctuation\">[</span>key<span class=\"token punctuation\">]</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"28\"></td><td><pre>\t\t<span class=\"token function\">QuickSort</span><span class=\"token punctuation\">(</span>arr<span class=\"token punctuation\">,</span> begin<span class=\"token punctuation\">,</span> left <span class=\"token operator\">-</span> <span class=\"token number\">1</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"29\"></td><td><pre>\t\t<span class=\"token function\">QuickSort</span><span class=\"token punctuation\">(</span>arr<span class=\"token punctuation\">,</span> left <span class=\"token operator\">+</span> <span class=\"token number\">1</span><span class=\"token punctuation\">,</span> end<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></pre></td></tr><tr><td data-num=\"30\"></td><td><pre>\t<span class=\"token punctuation\">&#125;</span></pre></td></tr><tr><td data-num=\"31\"></td><td><pre><span class=\"token punctuation\">&#125;</span></pre></td></tr></table></figure><h6 id=\"优化效果\"><a class=\"anchor\" href=\"#优化效果\">#</a> 优化效果</h6>\n<p>对于随机序列，随机选 key 和三数取中法并没有太大的作用：</p>\n<p><img data-src=\"test2.png\" alt=\"1000万随机数测试\" /></p>\n<p>但是如果是有序或者近有序序列，就完爆原版了：</p>\n<p><img data-src=\"test3.png\" alt=\"十万有序数测试\" /></p>\n<p>而小区间优化，说实话效果有限：</p>\n<p><img data-src=\"test4.png\" alt=\"1000万随机数测试\" /></p>\n<h5 id=\"稳定性-6\"><a class=\"anchor\" href=\"#稳定性-6\">#</a> 稳定性</h5>\n<p>快速排序是不稳定的。</p>\n<hr />\n<div class=\"note info\">\n<p>未完待续。</p>\n</div>\n",
            "tags": [
                "计算机科学",
                "数据结构笔记",
                "算法",
                "数据结构",
                "排序"
            ]
        }
    ]
}